尝试使用递归来压缩字符串时遇到了一些麻烦。
例如,请考虑以下字符串:
qwwwwwwwwweeeeerrtyyyyyqqqqwEErTTT
应用RLE算法后,此字符串将转换为:
q9w5e2rt5y4qw2Er3T
在压缩字符串中,“9w”表示9个连续小写“w”字符的序列。 “5e”代表5个连续的小写“e”字符等。
我已经有了一个压缩代码而没有递归的代码:
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Compress {
public static String input(String source) {
StringBuffer coding = new StringBuffer();
for (int i = 0; i < source.length(); i++) {
int runLength = 1;
while (i+1 < source.length() && source.charAt(i) == source.charAt(i+1)) {
runLength++;
i++;
}
if (runLength>1){
coding.append(runLength);
}
coding.append(source.charAt(i));
}
return coding.toString();
}
public static void main(String[] args) {
IO.outputStringAnswer("Enter a string");
String str = IO.readString();
String result = "";
result=input(str); //function(variable)
IO.outputStringAnswer(result);
}
}
但我不确定这是否可以变成这个的递归版本。
答案 0 :(得分:4)
这很可能是您正在寻找的:
public static String compress(String source) {
if (source.length() <= 1) return source;
int runLength = 1;
while (runLength < source.length() && source.charAt(0) == source.charAt(runLength)) {
runLength++;
}
String lengthString = runLength > 1 ? String.valueOf(runLength) : "";
return lengthString + source.substring(0,1) + compress(source.substring(runLength));
}
我假设您的源字符串不包含任何数字。正如您所看到的,函数在最后一行中使用源字符串的其余部分递归调用自身。
答案 1 :(得分:2)
这是一个有趣的问题。一种根本不使用迭代的解决方案,只有递归:
public static String compressRecursion(String str, char curChar, int curCount) {
// termination case - reached end of the source string
if(str.length() == 0)
return "" + (curCount == 1 ? "" : curCount) + curChar;
// branch on change in next character
String nextStr = str.substring(1,str.length());
if(str.charAt(0) == curChar)
return compressRecursion(nextStr,curChar,curCount + 1);
else
return "" + (curCount == 1 ? "" : curCount) + curChar
+ compressRecursion(nextStr,str.charAt(0),1);
}
public static String compress(String source) {
return compressRecursion(source, source.charAt(0), 0);
}
这可能在生产代码中没有多大用处,因为在任何合理长度的输入下都会发生“Stack Overflow”异常,这是因为将为每个函数调用创建一个新的堆栈帧,从而为输入。 Java实际上并不是为运行这样的代码而设计的。
用scheme编写的同义压缩函数(没有迭代结构):
(define (num2str num)
(if (= 1 num) "" (number->string num)))
(define (first-char str)
(substring str 0 1))
(define (next-string str)
(substring str 1 (string-length str)))
(define (compress str char count)
(cond [(= 0 (string-length str)) (string-append (num2str count) char)]
[(string=? char (first-char str))
(compress (next-string str) char (+ count 1))]
[ else
(string-append (num2str count) char
(compress (next-string str) (first-char str) 1))]))
(define (compressStart str)
(compress str (first-char str) 0))
像scheme这样的函数式语言将使用尾递归优化来防止堆栈溢出,并使函数调用比Java等命令式语言更轻量级的操作。