0

im trying to do this probelm "Check to see if a string has the same amount of 'x's and 'o's. The method must return a boolean and be case insensitive. The string can contain any char."

However i am failing a few tests so i am wondering is there a better way of doing this?

public class XO {

  public static boolean getXO (String str) {
  boolean Boolean = false;
    String[] x = str.split("x");
    String[] o = str.split("o");
    // Good Luck!!
    if(x.length == o.length){
    Boolean = true;
    }
    return Boolean;
  }
}

4 Answers4

2

Your method does not appear to be case insensitive; I would loop over all of the letters in the input String (after first converting it to lower case) and count the x and o characters. Something like,

int x = 0, o = 0;
for (char ch : str.toLowerCase().toCharArray()) {
    if (ch == 'x') {
        x++;
    } else if (ch == 'o') {
        o++;
    }
}
return o == x;
Elliott Frisch
  • 198,278
  • 20
  • 158
  • 249
  • 1
    `toLowerCase()` *and* `toCharArray()`? Are we *made* of money? – Andy Turner Jul 24 '19 at 20:47
  • @AndyTurner I could have written `return IntStream.range(0, str.length()).filter(i -> str.charAt(i) == 'X' || str.charAt(i) == 'x').count() == IntStream.range(0, str.length()).filter(i -> str.charAt(i) == 'Y' || str.charAt(i) == 'y').count();` – Elliott Frisch Jul 24 '19 at 21:03
2

You don't need to do any splitting. Aside from the fact it's not correct (try oooxxx, for example, or OOOxxx), it's rather inefficient, because it requires creating new objects. You don't need to do this.

Just iterate a character at a time, checking what the current character is, and increment/decrement a counter:

int count = 0;
for (int i = 0; i < str.length(); ++i) {
  switch (str.charAt(i)) {
    case 'o': case 'O':
      count++;
      break;
    case 'x': case 'X':
      count--;
      break;
  }
}
return count == 0;

Prefer using an indexed loop and charAt rather than iterating toCharArray(), because the latter creates a new char array containing the whole string.

Andy Turner
  • 137,514
  • 11
  • 162
  • 243
0

I suggest you take a look at this post. You could do something like

return StringUtils.countMatches(str, "x") == StringUtils.countMatches(str, "o").

Why invent the wheel twice? Let me know if that helps you. I did not try the code, but it should work.

Lukas Nothhelfer
  • 820
  • 1
  • 7
  • 23
0

There are actually many different ways to accomplish thhis:

  • Count Occurrences of a Char in a String
    • Imperative Approach
    • Using Recursion
    • Using Regular Expressions
    • Using Java 8 Features
    • Using 3rd party libraries (notably Apache Commons or Spring Framework)

This example is something I might try (at least as a first cut, before "optimizing"):

public static boolean isSameXOCount (String str) {
  int ctX = 0, ctO = 0;
  for (int i=0; i < str.length; i++) {
    char c = str.charAt(i);
    if (c == 'X' || c == 'x')
      ctX++;
    else if (c == 'O' || c == 'o')
      ctO++;
  }
  return ctX == ct);
}
paulsm4
  • 114,292
  • 17
  • 138
  • 190