Search code examples
javarecursioncountwords

Java recursive method for counting words


I should first of all say this is an assignment that is confusing me, I've already corrected one of the questions by the lecturer :/

Anyway, I've made a method which counts the words using booleans, a while loop and a counter.

However I need to some how shape this into a recursive method that counts the amount of words in a string, a word is delimited by one or many spaces.

countWords(" hello this is an example", 0); // returns 5

As you can see the only parameters are countWords(String s, int i) making it more difficult.

Also, within the method I'm restricted to only using these three methods s.charAt(0), s.substring(1) and s.equals("") again making it more of a head hurter :)

This is the none recursive method I wrote using a while loop:

public static int countWords(String s) {
    int words = 0;
    boolean spaceBefore = true;
    boolean spaceCurrently = false;
    while(true) {
        if (s.equals(""))
            return words;

        if (s.charAt(0) == ' ')
            spaceCurrently = true;
        else
            spaceCurrently = false;

        if (spaceBefore && !spaceCurrently)
            words++;        

        spaceBefore = spaceCurrently;
        s = s.substring(1);
    }
}

Solution

  • Well since this is a homework assignment, I'll refrain from giving you the code. But I'll explain the solution to you. See if you can rebuild the code from it.

    In the method, first remove the white spaces from the beginning and end of the line since we want to ignore it. Use the trim() method for that. Next check if the string is an empty string ("") like you did in the code. If it is, then return a zero because an empty string contains no words, otherwise in an infinite loop (while (true)) check the following conditions:

    • Create a variable to hold the current index, one which is not local to the loop, but it local to the method. For each iteration of the infinite loop, check if the current character (using the charAt() method) is not a space and that the index is less than the length of the string. If this condition is true, increment the index variable.
    • If not, check if the index variable is equal to the length of the string. If yes, then return a 1, because it means that we have reached the last word of the string.
    • If not, return the sum of 1 and the method to count words, recursively called for the substring from the current value of index.

    This should get you the value. If you are still unable to do it, let me know and I'll give you the source.

    EDIT Well if you cannot use String's trim method, you can write one for yourself like this. I believe it does not violate any of your requirements:

    private String trim(String str) {
        int beginIndex = 0;
        int endIndex = str.length() - 1;
    
        while (true) {
            if (str.charAt(beginIndex) == ' ') {
                beginIndex++;
            } else if (str.charAt(endIndex) == ' ') {
                endIndex--;
            } else {
                break;
            }
        }
    
        return str.substring(beginIndex, endIndex);
    }
    

    Edit 2 If you cannot use length() either, then modify the above line of code int endIndex = str.length() - 1;' toint endIndex = getLength(str) - 1;` and use the following code for calculating length.

    private int getLength(String str) {
        int length = 0;
    
        while (true) {
            try {
                str.charAt(length++);
            } catch (StringIndexOutOfBoundsException e) {
                break;
            }
        }
        return --length;
    }
    

    Edit 3 Since the question is such a PITA, it would be difficult to explain in words. So here's the code:

    private int countWords(String searchString) {
        int index = 0;
        boolean beginning = true;       // to check if it's the beginning of the line
    
        if (searchString.equals("")) {
            return 0;
        } else {
            while (true) {
                try {
                    if (searchString.charAt(index) != ' ') {
                        beginning = false;
                        index++;
                    } else {
                        if (!beginning) {
                            return 1 + countWords(searchString.substring(++index));
                        } else {
                            return countWords(searchString.substring(++index));
                        }
                    }
                } catch (StringIndexOutOfBoundsException e) {
                    if (!beginning) {
                        return 1;
                    } else {
                        return 0;
                    }
                }
            }
        }
    }
    

    This would help you achieve what you want with only the methods you are allowed to use.