Reputation: 273
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
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
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
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