Debugging Practice

From CompSciWiki
Revision as of 16:19, 4 December 2011 by AdamW (Talk | contribs)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

Back to the Program-A-Day homepage

Problem

The code provided below was written by a student who was challenged to write a program that reversed every word in a provided sentence. After testing it successfully with a single word, the student was confident that the code would work for a full sentence. Unfortunately, that is not the case. Find all the bugs in the student's code, and fix them. Hint: There are three of them.

 import javax.swing.JOptionPane;

public class WordReversal 
{
    public static void main( String[] args ) 
    {
        int lastSpace = 0; //position of the last space we found
        int nextSpace = 0; //position of the next space
        String result = ""; //final result
        String reversedWord = ""; //temporarily holds a reversed word
        String currWord = ""; //the current word we are reversing

        //get input from the user
        String input = JOptionPane.showInputDialog( "Enter a sentence:" );

        //keep looping until we don't find a new space
        while( nextSpace >= 0 )
        {
            //finds the next space in the sentence
            nextSpace = input.indexOf( ' ', lastSpace );

            if( nextSpace != -1 ) 
            {
                //space was found, grab the word between the spaces
                currWord = input.substring( lastSpace, nextSpace + 1 );
            } 
            else 
            {
                //no more space was found, just grab the rest of the sentence
                currWord = input.substring( lastSpace, input.length() );
            }

            //reverse the word
            for( int j = currWord.length() - 1; j >= 0; j-- ) 
            {
                reversedWord = reversedWord + currWord.charAt( j );
            }

            //add the reversed word to the result so far
            result = result + reversedWord;
        }

        //output the result
        JOptionPane.showMessageDialog( null, result, "Reversed Words",
                JOptionPane.INFORMATION_MESSAGE );
    }
} 
 

String Methods and Debugging

Wiki array02.jpg

Solution

If you were to run the above code for anything that is longer than a single word, the program enters an infinite loop, and eventually crashes due to a stack overflow. Since there are two loops in the code, we need to figure out which one is the culprit. The inner loop, being a for loop, is rather unlikely to be causing this, so it is likely the outer while loop that is causing problems. Since our termination condition is based on not finding the next space, there must logically then be something wrong with that part of our algorithm. Going through a full loop's iteration line by line either in your head or on paper is usually a good tool to debug this kind of buggy loop. If you were to do that here, you would likely quickly notice that we never update our lastSpace position -- which is where we start looking for the next space. This is quickly fixed by adding the following line at the end of the while loop:

 lastSpace = nextSpace; 

However, if you were to run the code after adding this line, you'd notice this still hasn't fixed our problem! It is clear now that there's something that isn't quite working as we expected it to. In this situation, it is often helpful to add some print statements that output values of different variables at each loop iteration, and see what's not working. If you were to do that here, you'd notice that we're not really finding the next space -- we're finding the same one over and over again! A quick modification to our indexOf call should fix that:

 nextSpace = input.indexOf( ' ', lastSpace + 1 ); 

Now that's solved our pesky infinite loop problem. The only problem now is that our output seems a bit wonky -- it's reversing words, but some of them appear more than once. Here is a case where the output you're getting gives you a strong hint as to what could be wrong. In this particular case, it seems we have a variable we're not resetting. This can be deduced by the pattern of repetition we see in our output. To fix this, simply add the following line before the inner for loop:

 reversedWord = ""; 

The program should now work perfectly :)

Code

Solution Code

Back to the Program-A-Day homepage