3
\$\begingroup\$

I already solved this one from CodingBat, but I'm unsatisfied with my solution and I feel I could have made it much shorter. Most of the other recursion tasks could be solved by a one line conditional for the base case and a one line return statement usually using ternary operator. So, could I have made this any shorter or more readable?

Given a string, compute recursively the number of times lowercase "hi" appears in the string, however do not count "hi" that have an 'x' immedately before them.

public int countHi2(String str) {
  if (str.length() <= 1) {
    return 0;
  }


  if (str.startsWith("x") && str.charAt(1) != 'x') {
    return countHi2(str.substring(2));
  }
  else if (str.startsWith("hi")) {
    return 1 + countHi2(str.substring(2));
    }
  else {
    return countHi2(str.substring(1));
  }
}
\$\endgroup\$
1
\$\begingroup\$

It doesn't get much shorter than that. But some other improvements are possible.

The current algorithm uses startswith method to check for x and hi, and as such it advances by 1 or 2 characters at a time. This is inefficient.

Another performance issue is creating many temporary strings in the process (because of substring).

It would be better to use indexOf instead of startswith, which will allow you to jump multiple characters at a time. Another big improvement would be to avoid temporary string generation, by creating a helper function that tracks the position to check. Something like this:

public int countHi2(String str) {
    return countHi2(str, 0);
}

public int countHi2(String str, int start) {
    start = str.indexOf("hi", start);
    if (start == -1) {
        return 0;
    }

    int count = 0;
    if (start == 0 || str.charAt(start - 1) != 'x') {
        count++;
    }
    return count + countHi2(str, start + 2);
}
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.