Mohamed Hegazy
Mohamed Hegazy

Reputation: 273

what is the significance of placing a variable inside a for loop rather than outside in JavaScript?

I don't think this is a matter of global-local variables as the duplicate bot suggested because when I edited the wrong code and placed the counter variable inside the for loop, the same wrong output was given.

I was trying to write a function which counts the number of instances an input word/character occurs.

the test data were :

1- input (find('The quick brown fox', 'fox')) , output (“fox was found 1 times”)

2- input (find('aa, bb, cc, dd, aa', 'aa')) , output(“aa was found 2 times”)

I have attempted to solve it two times, first time the output was ”fox was found 6.333333 times ” and the second solution gave an output “fox was found 1 times”.

The difference between the two methods I attempted was the position of the final output counter and the syntax used.

first attempt:

function find(str,key){ 
var count = 0;
var answer = 0;
    for (var i = 0; i<str.length; i++){ 
        if (str[i] == key[0] ){
            for (var j = i; j<i +str.length; j++){
                if (str[j] == key[j-i]){ 
                    count = count + 1;
                }       
            }
        }
    }

    answer = (count)/(key.length);
    return key + "was found " + answer + "times";

}

second attempt:

function find(str,key){ 
var count = 0;
var answer = 0;
    for (var i = 0; i<str.length; i++){ 

        if (str[i] == key[0] ){ 

            for (var j = i; j<i +str.length; j++){    

                if (str[j] == key[j-i]){  
                    count = count + 1;
                }

                if (count == key.length){answer = answer + 1;}
            }
        }
    }
    return key + "was found " + answer + "times";
}

I am not sure why the first one did not work, and what happened inside my code that yielded an answer of 6.3333 rather than 1?

Upvotes: 1

Views: 69

Answers (3)

Ilya
Ilya

Reputation: 5557

You have two problems in you first attempt, see comments in the (fixed) code below

function find(str,key){ 
    var count = 0;
    var answer = 0;
    for (var i = 0; i<str.length; i++){ 
        if (str[i] == key[0] ){
            for (var j = i; j<str.length; j++){  // you have to stop at end of "str"!
                if (str[j] == key[j-i]){ 
                    count = count + 1;
                }
                else {
                    break; // no match, you have to restart at beginning of "key"
                }       
            }
        }
    }

    answer = (count)/(key.length);
    return key + "was found " + answer + "times";

}

NB there's a third problem that's potentially fixed by your 2nd version (potentially because there's bugs in it too). The problem is that partial matches should count for zero and not n/key.length (an example is provided in the comments by @TheGreatContini).

While we're at it, here is a fix to the 2nd one

function find(str,key){ 
    var count = 0;
    var answer = 0;
    for (var i = 0; i<str.length; i++){ 

        if (str[i] == key[0] ){ 

            for (var j = i; j<str.length; j++){ // same problem here

                if (str[j] == key[j-i]){  
                    count = count + 1;
                }
                else { 
                    count = 0;
                    break; // you have to restart
                }

                if (count == key.length){
                     count = 0;   // a new beginning
                     answer = answer + 1;
                 }
            }
        }
    }
    return key + "was found " + answer + "times";
}

PS as a bonus, here is a more efficient string matching algorithm - O(str.length) instead of O(str.length*key.length).

Upvotes: 1

TheGreatContini
TheGreatContini

Reputation: 6629

Every time you do a for j loop, you need to initialise count to 0.

A new loop is the beginning of a new word comparison. You only increment answer if count reaches the full length of the word. So you are always going to need a if (count == key.length){answer = answer + 1;}.

BTW, your for i loop should not go up to str.length, instead subtract key.length from it.

Upvotes: 1

ManoDestra
ManoDestra

Reputation: 6473

You're dividing count by key.length in the first example, hence why you get a decimal value (19/3 = 6.333, where 19 is the length of the input). The second example only increments answer, hence why it's an integer value.

Upvotes: 1

Related Questions