我正在尝试用 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();
}
}
我的递归基本情况是一个空字符串,如果字符串以字母开头,则该字母仅添加到字符串缓冲区 newString 一次,并且原始字符串的第一个字母将从字符串序列中删除,新字符串是传递给解压;如果它以零数字开头,则删除字符串的前两个字符,并将新字符串传递到解压缩。
如果它是一个大于 0 的数字[else],则将其前面的字母添加到字符串缓冲区 newString 中,并将该数字递减并替换字符串开头的数字,并将新字符串[与原始字符串一起传递]第一个字符编号 - 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
创建一个新的StringBuffer
,因为这样每次decompress
都会被调用一个新的StringBuffer
将被创建,这不是您想要的。如果 decompress
采用 StringBuffer newString
参数,并且每次 decompress
调用自身时都会将 newString
作为参数传递,那么每个decompress
调用都将指向相同StringBuffer
,因为它是对对象的引用。
我认为您暗示的另一种方法是,由于 decompress
返回一个 String
,因此每次 decompress
调用自身时,它都可以< em>使用函数结果(现在您的代码只是将其丢弃),并且可能将该函数结果与其他内容连接起来并返回新字符串。我认为你可以使这种方法发挥作用,但我还没有彻底研究它。
关于java - 递归Java RLE解压方法【stackoverflow错误】,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20256292/