1

the code below is meant to count each time character 'x' occurs in a string but it only counts once ..

I do not want to use a loop.

public class recursionJava

{

   public static void main(String args[])

   {

      String names = "xxhixx";

      int result = number(names);
      System.out.println("number of x: " + result);
   }

   public static int number (String name)
   {

      int index = 0, result = 0;

      if(name.charAt(index) == 'x')
      {
         result++;
      }
      else
      {
         result = result;
      }
            index++;

      if (name.trim().length() != 0)
      {
        number(name);
      }
      return result;
   }
}
Federico klez Culloca
  • 26,308
  • 17
  • 56
  • 95
Atinuke
  • 191
  • 2
  • 4
  • 11

6 Answers6

6

You could do a replacement/removal of the character and then compare the length of the resulting string:

String names = "xxhixx";
int numX = names.length() - names.replace("x", "").length(); // numX == 4
Tim Biegeleisen
  • 502,043
  • 27
  • 286
  • 360
5

If you don't want to use a loop, you can use recursion:

public static int number (String name)
{
    if (name.length () == 0)
        return 0;
    int count = name.charAt(0)=='x' ? 1 : 0;
    return count + number(name.substring(1));
}
Eran
  • 387,369
  • 54
  • 702
  • 768
4

As of Java 8 you can use streams:

"xxhixx".chars().filter(c -> ((char)c)=='x').count()
Luk
  • 2,186
  • 2
  • 11
  • 32
4

Previous recursive answer (from Eran) is correct, although it has quadratic complexity in new java versions (substring copies string internally). It can be linear one:

    public static int number(String names, int position) {
    if (position >= names.length()) {
        return 0;
    }

    int count = number(names, position + 1);

    if ('x' == names.charAt(position)) {
        count++;
    }
    return count;
}
Maciej
  • 1,954
  • 10
  • 14
2

Your code does not work because of two things:

  1. Every time you're calling your recursive method number(), you're setting your variables index and result back to zero. So, the program will always be stuck on the first letter and also reset the record of the number of x's it has found so far.
  2. Also, name.trim() is pretty much useless here, because this method only removes whitespace characters such as space, tab etc.

You can solve both of these problems by

  1. making index and result global variables and
  2. using index to check whether or not you have reached the end of the String.

So in the end, a slightly modified (and working) Version of your code would look like this:

public class recursionJava {

    private static int index = 0;
    private static int result = 0;

    public static void main(String[] args) {
        String names = "xxhixx";

        int result = number(names);
        System.out.println("number of x: " + result);
    }

    public static int number (String name){
        if(name.charAt(index) == 'x')
            result++;

        index++;

        if(name.length() - index > 0)
            number(name);
        return result;
    }

}
hensing1
  • 187
  • 13
1

You can use StringUtils.countMatches

StringUtils.countMatches(name, "x");

Pelin
  • 936
  • 5
  • 12
  • That uses a loop internally. – Kayaman Mar 05 '18 at 08:44
  • 2
    @Kayaman So does the String method `replace` used in the current highest voted answer. – OH GOD SPIDERS Mar 05 '18 at 08:54
  • @OHGODSPIDERS that's true, but you're not really putting them on the same line are you. – Kayaman Mar 05 '18 at 08:57
  • I think recursion is an interesting solution and I would recommend to use this approach during a job interview etc. , but for a real life project the StringUtils class provides simpler and cleaner usage. – Pelin Mar 05 '18 at 09:30
  • I suppose you are referring to [Appache Commons `StringUtils.countMatches`](https://commons.apache.org/proper/commons-lang/apidocs/org/apache/commons/lang3/StringUtils.html#countMatches-java.lang.CharSequence-char-) - might be worth mentioning that. – Hulk Mar 05 '18 at 12:05