0

I am trying to write a program in Java that decompresses a compressed RLE statement using recursion, but I am continuously getting stack overflow errors and I do not know why.

Here is what I wrote thus far:

public class StringRec
{
    public static void main (String args[]){

        System.out.println(decompress("wed4d"));
    }
    //Version 0.1
    public static String decompress(String compressedText)
    {   String cText = compressedText; 
        StringBuffer newString = new StringBuffer();

        int i = 0;

        if (cText==""){return newString.toString();}

        if(!cText.isEmpty()){

            if(Character.isLetter(cText.charAt(i))){
                newString.append(cText.charAt(i));

                cText = cText.substring(1,cText.length());  

                return decompress(cText);
                //remove first letter, return new modified string with removed first letter to decompress.
            }
            if(Character.isDigit(cText.charAt(i))){
                 int c = cText.charAt(i)-'0';

                if (c==0){
                    cText = cText.substring(2,cText.length());}

                    return decompress(cText);   
                    //delete c and the letter after it and send new modified string to decompress.
                    }

                }else {
                    newString.append(cText.charAt(i+1));
                    int c = cText.charAt(i);
                    c--;
                    String num = ""+c;
                    cText = cText.replaceFirst(num, Character.toString(cText.charAt(i)));

                    return decompress(cText);
                    //appends character after number to newString, decrements the number and returns
                    //the new modified string to decompress with the first number decremented by one
                    }
        return newString.toString(); 

    }
}

My base case for the recursion is an empty string, if the string starts with a letter that letter is added to the stringbuffer newString only once and that first letter of the original string is deleted from the string sequence and the new string is passed to decompress; if it starts with a number that is zero then the first two chars of the string are deleted and the new string is passed to decompress.

If it's a number greater than 0[else] then the letter in front of it is added to the stringbuffer newString and the number is decremented and replaces the number in the beginning of the string and passes the new string [with the original first char number - 1] to decompress.

4
  • How long is the string? Java does not support unlimited recursion; recursive algorithms only work if they don't recurse too deep. Commented Nov 28, 2013 at 1:42
  • Don't know about the stack overflow, but every time you call decompress recursively, the recursive routine will create a new newString. The new call of the routine will not append to the same newString that the old call was using. Your recursive method will probably need to take newString as a parameter that it keeps passing to itself, and then an outside non-recursive routine will need to initialize it before calling the recursive routine for the first time. Commented Nov 28, 2013 at 1:43
  • Have you tried stepping through your code in a debugger? That and a few well placed System.out.println logging calls would help you find out why your recursion is not reaching the base case and causing the error... Commented Nov 28, 2013 at 1:50
  • @user3003741 - i rolled back your last changes because it significantly changed the question & formatting, and included a new inappropriately named function at the end. A different problem with new code should probably be posted as its own question. You may also want to consider the StackOverflow chat system for problems with a lot of back and forth. Commented Nov 28, 2013 at 7:41

1 Answer 1

1

I believe the infinite recursion is occurring because of this:

int c = cText.charAt(i);
c--;
String num = ""+c;
cText = cText.replaceFirst(num, Character.toString(cText.charAt(i)));

If the character is 1, then c will be 65, the ASCII value of the character '1'. Then num will be set to the string "64", and if there's no "64" in your string, the method will keep calling itself with the same string over and over. Declaring c as a char should fix that. Plus, note that replaceFirst says to search for a pattern that matches the first argument, and replace it with the second. You may have this backwards. Also, see my comment above about newString.

EDIT:To answer your comment: Using a StringBuffer is OK. What you cannot do is have each decompress create a new StringBuffer, because then each time decompress is called a new StringBuffer will be created, which isn't what you want. If decompress takes a StringBuffer newString parameter, and each time decompress calls itself it passes newString as a parameter, then every decompress call will point to the same StringBuffer, since it's a reference to an object.

The other approach that I think you hinted at was that since decompress returns a String, then every time decompress calls itself it can use the function result (right now your code is just throwing it away), and perhaps concatenate that function result with something else and return the new string. I think you can make this approach work, but I haven't studied it thoroughly.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks, I fixed it and will post the updated code. Can you further expand on the newString and the recursive routine? How would I go about doing that? Can I just change it up and have that string buffer be a normal String and I concatenate it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.