chopper draw lion4
chopper draw lion4

Reputation: 13487

Counting occurances of character in strings

I made a function that counts the occurances of x's and o's in a given string and returns true if they are equal.

function ExOh(str) { 
  var x_count = 0;
  var o_count = 0;

  for (var i = 0;i < str.length-1;i++){
    if (str[i] === 'x'){
      x_count = x_count + 1;
    }
    else if (str[i] === 'o'){
      o_count = o_count + 1;
    }
  }

  console.log(o_count);
  console.log(x_count);
  if (x_count === o_count){
    return true;}
  else{
    return false;
  }

}
// keep this function call here 
// to see how to enter arguments in JavaScript scroll down
ExOh(readline());   

I added the lines of code

  console.log(o_count);
  console.log(x_count);

To see if it was counting correctly and I discovered that was the issue. After testing it I realized that this function is not testing the last element in the string. I tried changing the length of the for loop, but I can't think of what else could be wrong.

Any advice?

Thanks mates

Upvotes: 0

Views: 198

Answers (5)

Paul S.
Paul S.

Reputation: 66304

Rather than looping over the whole String with for, I'd see if using indexOf achieves a faster result

function countOccurance(haystack, needle) {
    var total = 0, pos = -1;
    while (-1 !== (pos = haystack.indexOf(needle, pos + 1)))
        total += 1;
    return total;
}

Then

var x_count = countOccurance(str, 'x'),
    o_count = countOccurance(str, 'o');

return x_count === o_count;

EDIT looks like I might have been wrong about it being faster! jsperf

function indexOfMethod(haystack, needle) {
    var total = 0, pos = -1;
    while (-1 !== (pos = haystack.indexOf(needle, pos + 1)))
        total += 1;
    return total;
}
function splitMethod(haystack, needle) {
    return haystack.split(needle).length - 1;
}
function forMethod(haystack, needle) {
    var total = 0, i;
    for (i = 0; i < haystack.length; ++i)
        if (haystack.charAt(i) === needle)
            total += 1;
    return total;
}

The forMethod will only work with char needle, whereas the other two should work with any String as needle, if that matters.

Upvotes: 0

tarmaq
tarmaq

Reputation: 422

Your problem is in for loop. Try changing to this.

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

If you want to avoid using for loops, you can use this much shorter version of ExOh function.

function ExOh(str) { 
  return str.match(/o/g).length == str.match(/x/g).length
}

Upvotes: 0

Tyler McGinnis
Tyler McGinnis

Reputation: 35276

Your for loop is running one too short. Try this instead.

  for (var i = 0;i < str.length;i++){
    if (str[i] === 'x'){
      x_count = x_count + 1;
    }
    else if (str[i] === 'o'){
      o_count = o_count + 1;
    }
  }

Upvotes: 0

thefourtheye
thefourtheye

Reputation: 239443

JavaScript arrays are 0 index based objects. So, your loop should be like this

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

otherwise the last element will be skipped.

Consider that the length of the string is 5. So, i starts from 0 and if you had your original condition

for (var i = 0; i < str.length - 1; i++) {

following are the comparisons happening in the loop

0 < 4
1 < 4
2 < 4
3 < 4
4 < 4 -- Fails

So it breaks out of the loop. But the last element will be at index 4. But when you have the condition like this

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

the comparisons go like this

0 < 5
1 < 5
2 < 5
3 < 5
4 < 5
5 < 5 -- Fails

It breaks out of the loop only after comparing all the elements.

So, your actual program can be written like this

function ExOh(str) {
    var x_count = 0, o_count = 0;

    for (var i = 0; i < str.length; i++) {
        if (str[i] === 'x') {
            x_count = x_count + 1;
        } else if (str[i] === 'o') {
            o_count = o_count + 1;
        }
    }

    return x_count === o_count;
}

Upvotes: 3

phylax
phylax

Reputation: 2086

alternate method to count characters:

var s = 'example';
s.split('').filter(function (i) { return i === 'e'; }).length; // 2

Upvotes: 0

Related Questions