递归Java RLE解压缩方法[stackoverflow错误]

时间:2013-11-28 01:40:19

标签: java string recursion stack-overflow compression

我正在尝试用Java编写一个程序,使用递归解压缩压缩的RLE语句,但我不断得到堆栈溢出错误,我不知道为什么。

这是我到目前为止写的:

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(); 

    }
}

我递归的基本情况是一个空字符串,如果字符串以字母开头,那个字母只被添加到stringbuffer newString一次,并且原始字符串的第一个字母从字符串序列中删除,新字符串是通过减压;如果它以一个零开头的数字开头,则删除该字符串的前两个字符,并将新字符串传递给解压缩。

如果它是一个大于0 [else]的数字,那么它前面的字母会被添加到stringbuffer newString中并且数字会递减并替换字符串开头的数字并传递新的字符串[与原始字符串一起]第一个字符编号 - 1]要解压缩。

1 个答案:

答案 0 :(得分:1)

我相信无限递归是因为:

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

如果字符为1,则c将为65,即字符'1'的ASCII值。然后num将设置为字符串"64",如果您的字符串中没有"64",则该方法将一直使用相同的字符串调用自身。将c声明为char应该可以解决这个问题。另外,请注意replaceFirst说要搜索与第一个参数匹配的模式,并将其替换为第二个参数。你可能会倒退。另外,请参阅上面关于newString的评论。

编辑:回答你的评论:使用StringBuffer就行了。您无法做的是每个decompress创建一个new StringBuffer,因为每次调用decompress时都会创建一个新的StringBuffer,不是你想要的。如果decompress采用StringBuffer newString参数,并且每次decompress调用自身,它会将newString作为参数传递,则每个decompress调用都将指向相同 StringBuffer,因为它是对象的引用。

我认为您提到的另一种方法是,由于decompress返回String,因此每次decompress调用自身时,它都可以使用该函数结果(现在你的代码只是抛弃它),并且可能将该函数结果与其他东西连接起来并返回新的字符串。我认为你可以使这种方法有效,但我还没有彻底研究过它。