Search code examples
arraysstringreversetraversal

Reverse printing words while maintaining order and number of spaces?


I am attempting to solve this problem but I'm not sure why my solution doesn't work. My attempts at debugging tell me that the solution is attempting to access indices outside of the bounds of some of the data structures, but this does not make sense to me as it seems like my for-loop test would would.

There are probably many other issues with this solution besides this.

I'm also 90% sure that there's a more efficient way to do this. Could you help me figure out what it is I've done wrong here?

If there is a more efficient solution, what would it be? I'm struggling to deal with keeping track of the same number of spaces in the same order in an efficient way.

If any more information is necessary, please let me know and I will update.

public static void printReversed(String line){
    Scanner console = new Scanner(line);
    ArrayList<String> list = new ArrayList<String>(); // keeps track of words in line
    int spaceOccur = 0; // keeps track of the number of times there are spaces
    while (console.hasNext()){
        list.add(console.next()); 
        spaceOccur++;
    }
    int[] spaces = new int[spaceOccur]; // keeps track of number of spaces for each occurrence of spaces
    int count = 0; // for spaces[] traversal

    // searches through original input to get number of spaces
    for (int i = 0; i < line.length() - 1; i++){ 
        if (line.charAt(i) ==  ' '){
            int j = i;
            int num = 0;
            // traversal through spaces to count how many
            while (line.charAt(j) == (' ')){ // first error here
                num++;
                j++;
            }
            i = j; // updates for loop counter to point past spaces
            spaces[count] = num; // saves number of spaces
            count++; 
        }
    }
    // printing reversed input
    for (int k = 0; k < list.size(); k++){ 
        // prints reversed chars
        for (int m = list.get(k).length(); m > 0; m++){
            System.out.print(list.get(k).charAt(m)); 
        }
        // prints spaces
        for (int n = 0; n < spaces[k]; n++){
            System.out.print(" ");
        }
    }
}

Solution

  • I'd say that you're on right tracks, but some places need some closer inspection. The first loop seems to have some problems: The j++ is probably the one that goes beyond boundaries of the array - at least if you have spaces at the end of your string. And the whole loop itself seems to ignore the last character of the line.

    Are you sure you even need this first loop? If I have understood correctly, the Scanner´s next() will give you strings between the spaces; in the case of two consecutive spaces I think it should return you an empty string. In this case you could just loop the list the way you do in the end of your function, and print a space character when you encounter an empty string in your list. Otherwise just print the word backwards, just like you already do (except that it should be m-- instead of m++ in the last for loop).

    But if the Scanner won't give you the empty strings when there are two or more consecutive space characters, I bet the string's split() method should work.