检查给定的字符串是否同构

时间:2018-09-10 18:31:13

标签: javascript algorithm

我找到了此段,并想在JS中实现它:

  

要使两个字符串同构,字符中所有出现的字符   字符串A可以替换为另一个字符以获得字符串B。   字符的顺序必须保留。必须一对一   将字符串A的每个字符映射到字符串B的每个字符。

     

papertitle将返回true。 eggsad将返回   假。 dggadd将返回true。

这是我的尝试:

console.log(isIsomorphic("egg", 'add')); // true
console.log(isIsomorphic("paper", 'title')); // true
console.log(isIsomorphic("kick", 'side')); // false

function isIsomorphic(firstString, secondString) {

  // Check if the same lenght. If not, they cannot be isomorphic
  if (firstString.length == secondString.length)
    return false

  var letterMap = {};

  for (var i = 0; i < firstString.length; i++) {
    var letterA = firstString[i],
      letterB = secondString[i];

    // If the letter does not exist, create a map and map it to the value
    // of the second letter
    if (letterMap[letterA] === undefined) {
      letterMap[letterA] = letterB;
    } else if (letterMap[letterA] !== letterB) {
      // Eles if letterA already exists in the map, but it does not map to
      // letterB, that means that A is mapping to more than one letter.
      return false;
    }
  }
  // If after iterating through and conditions are satisfied, return true.
  // They are isomorphic
  return true;
}

我对为什么有错误感到困惑。

2 个答案:

答案 0 :(得分:2)

您有一个简单的错字:

  if (firstString.length == secondString.length) {
    return false
  }

如果两个字符串长度相同,则返回false。更改为:

  if (firstString.length !== secondString.length) {
    return false
  }

console.log(isIsomorphic("egg", 'add')); // true
console.log(isIsomorphic("paper", 'title')); // true
console.log(isIsomorphic("kick", 'side')); // false

function isIsomorphic(firstString, secondString) {

  // Check if the same lenght. If not, they cannot be isomorphic
  if (firstString.length !== secondString.length) {
    return false
  }

  var letterMap = {};

  for (var i = 0; i < firstString.length; i++) {
    var letterA = firstString[i],
      letterB = secondString[i];

    // If the letter does not exist, create a map and map it to the value
    // of the second letter
    if (letterMap[letterA] === undefined) {
      letterMap[letterA] = letterB;
    } else if (letterMap[letterA] !== letterB) {
      // Eles if letterA already exists in the map, but it does not map to
      // letterB, that means that A is mapping to more than one letter.
      return false;
    }
  }
  // If after iterating through and conditions are satisfied, return true.
  // They are isomorphic
  return true;
}

答案 1 :(得分:1)

您的解决方案几乎是正确的,ggorlen已向您显示了解决方案。但是,我将为您提供另一种解决方案,对我来说似乎更优雅。让我们介绍同构签名的概念,它是一个字符串,对于彼此同构的所有字符串都是相似的。

示例:

  

论文:0,2; 1; 3; 4

     

标题:0; 2; 1; 3; 4

     

鸡蛋:0; 1,2

     

悲伤:0; 1; 2

     

dgg:0; 1,2

     

添加:0; 1,2

这个想法是按照字母的出现顺序显示它们的索引。本文中的p位于索引0和2上。a位于索引1上。e位于索引3上。r位于索引4上。让我们实现function,它获得同构签名:

function getIsomorphicSignature(input) {
    var helper = {};
    for (var i = 0; i < input.length; i++) {
        if (!helper[input[i]]) helper[input[i]] = [];
        helper[input[i]].push(i);
    }
    var output = [];
    for (var item in helper) output.push(helper[item].join(","));
    return output.join(";");
}

现在,如果要查看两个字符串是否同构,则可以比较它们的同构签名。该解决方案的优雅之处在于您拥有一个可存储的属性,该属性在这种比较中表示了很多字符串。例如,如果要将同构字符串分组为簇,则可以执行以下操作:

function clusterize(var inputStrings) {
    var output = {};
    for (int i = 0; i < inputStrings.length; i++) {
        var signature = getIsomorphicSignature(inputStrings[i]);
        if (!output[signature]) output[signature] = [];
        output[signature].push(inputStrings[i]);
    }
    return output;
}