【问题标题】:Using two for loops to compare two strings使用两个 for 循环比较两个字符串
【发布时间】:2017-01-08 04:31:29
【问题描述】:

我正在 exercism.io 上进行练习,第三个要求我们比较两个 DNA 字符串并返回它们之间的差异(汉明距离)。

例如:

GAGCCTACTAACGGGAT
CATCGTAATGACGGCCT
^ ^ ^  ^ ^    ^^

在该比较中排列了 7 个不同的字符。我的问题是我是否采取了正确的方法来解决这个问题。我创建了两个空数组,创建了一个循环遍历两个字符串并在它们相遇时推送不同字母的函数。

我尝试通过控制台运行它,但总是收到意外的输入错误。

    var diff = [];
    var same = [];
    function ham(dna1, dna2) {
      for (var i = 0; i < dna1.length; i++)
      for (var j = 0; j < dna2.length; i++){
        if (dna1[i] !== dna2[j]) {
          console.log(dna1[i]);
          diff.push(dna1[i]);
        }
        else {
          console.log(dna1[i]);
          same.push(dna1[i]);
        }
      return diff.length;
    }

    ham("GAGCCTACTAACGGGAT", "CATCGTAATGACGGCCT");
    console.log("The Hamming distance between both DNA types is " +                 diff.length + ".");

【问题讨论】:

  • 您在第一个循环中缺少 {}!
  • @SandeepNayak 第一个 for 中的唯一语句是第二个 for,因此尽管包含它们可能是一个好习惯,但 {} 并不是严格要求的。
  • @Dave,你能包括你得到的错误吗?
  • 你应该在 for 循环之外返回 diff.length
  • 您缺少第二个循环的 {} 或 ham 函数的 {}

标签: javascript


【解决方案1】:

不要使用全局变量。

如果没有必要,不要使用嵌套循环。

不要在数组中存储无用的东西。

function ham(dna1, dna2) {
  if (dna1.length !== dna2.length) throw new Error("Strings have different length.");
  var diff = 0;
  for (var i = 0; i < dna1.length; ++i) {
    if (dna1[i] !== dna2[i]) {
      ++diff;
    }
  }
  return diff;
}
var diff = ham("GAGCCTACTAACGGGAT", "CATCGTAATGACGGCCT");
console.log("The Hamming distance between both DNA types is " + diff + ".");

【讨论】:

    【解决方案2】:

    第一个问题是您缺少结束 }。我想你希望它在return 声明之前

    其次,你的算法有问题。您将dna1 (i) 中的每个项目与dna2 中的每个项目进行比较,而不是比较相同位置的项目。

    要使用一个更简短的示例以便我们逐步了解它,请考虑比较“CAT”和“CBT”。您想比较每个字符串中 same 位置的字符。因此,您实际上并不想要 2 个 for 循环,您只想要 1 个。您将 C 与 C ([0])、A 与 B ([1]) 和 T 与 T ([2]) 进行比较在 [1] 找到 1 个差异。现在在你的脑海中用你的 2 个for 循环逐步完成它,你会发现你会得到比现有更多的差异。

    一旦你对每个字符串中的字符使用相同的偏移量进行比较,你就不得不担心一个可能比另一个短。如果您尝试在字符串末尾使用偏移量,则会出现错误。所以我们也必须考虑到这一点,并假设将字符串长度之间的差异计算为差异。但也许这超出了您的范围,并且字符串将始终相同。

    【讨论】:

      【解决方案3】:

      你只需要一个循环,如下所示:

      var diff = [];
      var same = [];
      
      function ham(dna1, dna2) {
        for (var i = 0; i < dna1.length; i++) {
          if (dna1[i] !== dna2[i]) {
            console.log("not same");
            diff.push(dna1[i]);
          } else {
            console.log("same");
            same.push(dna1[i]);
          }
      
      
        }
      
      
        return diff.length;
      }
      
      ham("GAGCCTACTAACGGGAT", "CATCGTAATGACGGCCT");
      console.log("The Hamming distance between both DNA types is " + diff.length + ".");

      【讨论】:

        【解决方案4】:

        编辑距离并不难计算。需要更多代码来覆盖参数值中的边缘情况。

        function hamming(str1, str2) {
            var i, len, distance = 0;
        
            // argument validity check
            if (typeof str1 === "undefined" || typeof str2 === "undefined") return;
            if (str1 === null || str2 === null) return;
        
            // all other argument types are assumed to be meant as strings
            str1 = str1.toString();
            str2 = str2.toString();
        
            // the longer string governs the maximum edit distance
            len = str1.length > str2.length ? str1.length : str2.length;
        
            // now we can compare
            for (i = 0; i < len; i++) {
                if ( !(str1[i] === str2[i]) ) distance++;
            }
        
            return distance;
        }
        

        【讨论】:

          【解决方案5】:

          函数的执行:

          ham( "GAGCCTACTAACGGGAT", "CATCGTAATGACGGCCT" );
          

          以下函数定义:

          function ham(A,B){
             var D = [], i = 0;
             i = A.length > B.length ? A : B; 
          
             for( var x in i)
                A[x] == B[x] ? D.push(" ") : D.push("^");
          
             console.log( A + "\n" + B +"\n" + D.join("") );
          }
          

          将输出日志:

          GAGCCTACTAACGGGAT
          CATCGTAATGACGGCCT
          ^ ^ ^  ^ ^    ^^ 
          

          能够接收不同长度的字符串,根据需要和数据表示比较可以修改,用足够的标准符号等填充空白。

          演示:

          ham("GAGCCTACTAACGGGAT", "CATCGTAATGACGGCCT");
          
          function ham(A, B) {
            var D = [],
              i = 0;
            i = A.length > B.length ? A : B;
          
            for (var x in i)
              A[x] == B[x] ? D.push(" ") : D.push("^");
          
            console.log(A + "\n" + B + "\n" + D.join(""));
          };

          【讨论】:

            【解决方案6】:

            我认为你会想做这样的事情:

            var dna1 = "GAGCCTACTAACGGGAT";
            var dna2 = "CATCGTAATGACGGCCT";
            function ham(string1, string2) {
            var counter = 0;
            for (i = 0;i < string1.length;i++) {
            if (string1.slice(i, i + 1) != string2.slice(i, i + 1)) {
            counter++
            };
            };
            return(counter);
            };
            console.log("insert text here " + ham(dna1, dna2));
            

            它将字符串的每个字符与另一个字符串的相应字符进行比较,并在两个字符不相等时将计数器加 1。

            【讨论】:

              【解决方案7】:

              您可以使用Array#reduce 来迭代第一个字符串,通过使用Function#call,并将每个字母与第二个字符串中相应索引的字母进行比较。

              function ham(dna1, dna2) {
                return [].reduce.call(dna1, function(count, l, i) {
                  return l !== dna2[i] ? count + 1 : count;
                }, 0);
              }
              
              var diff =ham("GAGCCTACTAACGGGAT", "CATCGTAATGACGGCCT");
              console.log("The Hamming distance between both DNA types is " + diff + ".");

              【讨论】:

                猜你喜欢
                • 2013-04-05
                • 2013-06-06
                • 1970-01-01
                • 2018-05-23
                • 2020-05-17
                • 1970-01-01
                • 2012-08-07
                • 2013-11-15
                • 2021-10-10
                相关资源
                最近更新 更多