我正在尝试用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]要解压缩。
答案 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
调用自身时,它都可以使用该函数结果(现在你的代码只是抛弃它),并且可能将该函数结果与其他东西连接起来并返回新的字符串。我认为你可以使这种方法有效,但我还没有彻底研究过它。