davedeecoder
davedeecoder

Reputation: 235

Using two for loops to compare two strings

I am working through exercises on exercism.io and the third one asks us to compare two DNA strings and return the difference (hamming distance) between them.

So for example:

GAGCCTACTAACGGGAT
CATCGTAATGACGGCCT
^ ^ ^  ^ ^    ^^

There are 7 different characters lined up in that comparison. My question is whether I'm taking the right approach to solve this. I created two empty arrays, created a function that loops through both strings and pushes the different letters when they meet.

I tried running it through a console and I always get an unexpected input error.

    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 + ".");

Upvotes: 0

Views: 3298

Answers (7)

Ori Drori
Ori Drori

Reputation: 192006

You can use Array#reduce to iterate the 1st string, by using Function#call, and compare each letter to the letter of the corresponding index in the 2nd string.

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 + ".");

Upvotes: 0

milesman34
milesman34

Reputation: 96

I think that you would want to do something like this:

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));

It checks each character of the string against the corresponding character of the other string, and adds 1 to the counter whenever the 2 characters are not equal.

Upvotes: 0

Bekim Bacaj
Bekim Bacaj

Reputation: 5955

Execution of function:

ham( "GAGCCTACTAACGGGAT", "CATCGTAATGACGGCCT" );

of the following function definition:

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("") );
}

will output the log of:

GAGCCTACTAACGGGAT
CATCGTAATGACGGCCT
^ ^ ^  ^ ^    ^^ 

Is capable of receiving different length strings, which depending on the requirement and data representation comparison can be modified to fill the blank with adequate standard symbols etc.

Demo:

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(""));
};

Upvotes: 0

Tomalak
Tomalak

Reputation: 338248

The edit distance is not really hard to calculate. More code is needed to cover the edge cases in parameter values.

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;
}

Upvotes: 0

Oriol
Oriol

Reputation: 288290

Do not use globals.

Do not use nested loops if you don't have to.

Do not store useless things in arrays.

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 + ".");

Upvotes: 1

Sandeep Nayak
Sandeep Nayak

Reputation: 4757

You only need to have one single loop like below:

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 + ".");

Upvotes: 0

erik258
erik258

Reputation: 16304

The first problem is that you're missing a closing }. I think you want it right before the return statement.

secondly, there's a problem with your algorithm. You compare every item in dna1 (i) with every item in dna2 instead of coparing the item in the same position.

To use a shorter example so we can step through it, consider comparing 'CAT' and 'CBT'. you want to compare the characters in the same position in each string. So you don't actually want 2 for loops, you only want 1. You'd compare C to C ([0]), A to B ([1]), and T to T ( [2] ) to find the 1 difference at [1]. Now step through that with your 2 for loops in your head, and you'll see that you'll get many more differences than exist.

Once you use the same offset for the characters in each string to compare, you have to stat worrying that one might be shorter than the other. You'll get an error if you try to use an offset at the end of the string. So we have to take that into account too, and assumedly count the difference between string length as differences. But perhaps this is out of scope for you, and the the strings will always be the same.

Upvotes: 0

Related Questions