Help me explain this code

Discussion in 'JavaScript' started by saadi123, Jan 30, 2014.

  1. #1
    I was practising at the other site where I encountered the following Javascript code.

    function stringDistance(str1, str2){
    var numMismatch = 0;

    var index = 0;
    while (index < str1.length) {
    if (str1.charAt(index) !== str2.charAt(index)) {
    numMismatch++;
    }
    index++;
    }
    return numMismatch;

    }
    console.log(stringDistance("hat", "bat"));

    The code is returning the number of positions where the letters in the word differ with each other. For e.g the above code will return 1 since there's only one place where the two strings, which are "hat" and "bat", differ.

    What I want to know is that what is the purpose of the variable numMismatch in the above code. If I'm removing it, the console is returning "undefined". Can anybody explain me the purpose of this variable in particular?
     
    Solved! View solution.
    saadi123, Jan 30, 2014 IP
  2. HuggyStudios

    HuggyStudios Well-Known Member

    Messages:
    724
    Likes Received:
    20
    Best Answers:
    26
    Trophy Points:
    165
    #2
    numMismatch is incremented every time a match isn't found. After the loop it returns that number.
     
    HuggyStudios, Jan 30, 2014 IP
  3. saadi123

    saadi123 Well-Known Member

    Messages:
    196
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    101
    #3
    Hmmm...
    So the console actually displays the variable numMismatch when we run the program.
    And the misNummatch keeps adding up as long as it keeps finding different letters!
    @Huggy Studios Thanks for the clarification.
     
    saadi123, Jan 30, 2014 IP
  4. #4
    It's also poorly written -- no handling for if they are different lengths, multiple VAR declaration for nothing, "while" doing "for"'s job.

    function stringDistance(str1, str2) {
    	var
    		numMismatch = Math.abs(str1.length - str2.length),
    		last = Math.min(str1.length, str2.length);
    	
    	for (var index = 0; index < last; index++) {
    		if (str1.charAt(index) != str2.charAt(index)) numMismatch++;
    	}
    	return numMismatch;
    }
    Code (markup):
    It starts out making the number of mismatch equal to the difference in length (if any) between the two strings. If str2 is longer than the first the result would be negative, Math.abs forces it positive so it doesn't matter which is actually shorter. Ending the declaration in a comma means the 'var' statement also applies to the next item.

    The 'last' variable is then the shortest of the two string lengths; Math.min is a VERY powerful command once you understand what it does; feed it any number of values, it gives you whichever one is lowest.

    The 'for' loop then goes through each character in both strings up to the length of the shortest one... any mismatches we increment the counter.

    Then return that counter. The 'return' statement means that whatever you 'return' is the 'value' of that call to the function.

    With this routine you could test it thus:
    console.log(stringDistance("hat", "bat")); // outputs 1
    console.log(stringDistance("hatter", "bat")); // outputs 4
    console.log(stringDistance("hat", "batter")); // outputs 4
    console.log(stringDistance("hathor", "batter")); // outputs 3
    console.log(stringDistance("habitat", "battery")); // outputs 6
     
    deathshadow, Jan 31, 2014 IP
  5. saadi123

    saadi123 Well-Known Member

    Messages:
    196
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    101
    #5
    @deathshadow I have a question regarding your code.
    What's the point of declaring math.min since the code does not restrict itself to the lowest of the two strings.
    For e.g. in case of strings "hatter" and "bat", the lowest string length is 3 or in other words, last = 3;
    Now, if we run the for loop, we've set the index to 0. After that we want the numMismatch to increment as long as var index stays less than "last". In this case, it keeps incrementing as long as the index = 2.

    At the next line, where the charAt code is written, the code does not go through the whole "hatter" string because the charAt(index) does not go beyond 3 places (Since index never gets greater than 2).

    My question is that how come the "hatter" and "bat" and other code similar to it is resulting in the output of 4 since the code never reads the whole string.

    I don't know if you are following me!
     
    saadi123, Jan 31, 2014 IP
  6. deathshadow

    deathshadow Acclaimed Member

    Messages:
    9,732
    Likes Received:
    1,999
    Best Answers:
    253
    Trophy Points:
    515
    #6
    Ok, let's go through it by saying what the values would be if we passed 'hatter', 'bat' to the function...

    str1 = 'hatter'; so str1.length == 6
    str2 = 'bat'; so str2.length = 3
    numMismatch = 3; // 6 - 3
    last = 3; // smallest of 6 and 3

    Then let's unroll the loop -- that's what "for" does, it loops.
    First loop:
    index = 0;
    str1.charAt = 'h'
    str2.charAt = 'b'
    mismatch so numMismatch++; meaning numMismatch == 4

    Second loop:
    index = 1
    str1.charAt = 'a'
    str2.charAt = 'a'
    no mismatch

    Third loop:
    index = 2
    str1.charAt = 't'
    str2.charAt = 't'
    no mismatch

    Fourth loop:
    index = 3, no longer less than last, so exit loop

    return numMismatch, which is now 4.

    That's what you're missing -- if they are different lengths any characters past the length of the shortest string are automatically a mismatch, so we start with that as our numMismatch -- we don't need to check them one at a time as we KNOW they don't match (since they don't even EXIST in the other one), we only need to check character index's that EXIST in both strings.
     
    deathshadow, Feb 1, 2014 IP
  7. saadi123

    saadi123 Well-Known Member

    Messages:
    196
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    101
    #7
    WooooW!!!
    Now that's some explanation! Thanks for clearing it @deathshadow . I've got it now. Thanks for your time.
     
    saadi123, Feb 1, 2014 IP