递归解压一个字符串

问题描述:

我有这个任务,需要我解压缩一个以前压缩的字符串。这 例子是递归解压一个字符串

i4a --> iaaaa 
q3w2ai2b --> qwwwaaibb 
3a --> aaa 

这是我到目前为止已经写的:

public static String decompress(String compressedText) 
{ 
    char c; 
    char let; 
    int num; 
    String done = ""; 
    String toBeDone = ""; 
    String toBeDone2 = ""; 

    if(compressedText.length() <= 1) 
    { 
     return compressedText; 
    } 
    if (Character.isLetter(compressedText.charAt(0))) 
    { 
     done = compressedText.substring(0,1); 
     toBeDone = compressedText.substring(1); 

     return done + decompress(toBeDone); 
    } 
    else 
    { 
     c = compressedText.charAt(0); 
     num = Character.getNumericValue(c); 
     let = compressedText.charAt(1); 
     if (num > 0) 
     { 
      num--; 
      toBeDone = num + Character.toString(let); 
      toBeDone2 = compressedText.substring(2); 
      return Character.toString(let) + decompress(toBeDone) + decompress(toBeDone2); 
     } 
     else 
     { 
      toBeDone2 = compressedText.substring(2); 
      return Character.toString(let) + decompress(toBeDone2); 
     } 
    } 
} 

我的返回值是绝对可怕的。

"ab" yields "babb" somehow. 
"a" or any 1 letter string string yields the right result 
"2a" yields "aaaaaaaaaaa" 
"2a3b" gives me "aaaabbbbbbbbbbbbbbbbbbbbbbbbbbaaabbbbaaaabbbbbbbbbbbbbbbbbbbbbbbbbb" 

我可以看到一个错误,唯一的地方,很可能是最后一节别的,因为我并没有做什么,一旦数目达到0完全肯定,我必须停止使用该信递归之后。除此之外,我看不出有这样令人恐惧的输出的问题。

+0

你为什么要用递归来做这件事? –

+0

这是学习如何调试的好时机。 – shmosel

我觉得像这样的工作:

public static String decompress(String compressedText) { 
    if (compressedText.length() <= 1) { 
     return compressedText; 
    } 

    char c = compressedText.charAt(0); 

    if (Character.isDigit(c)) { 
     return String.join("", Collections.nCopies(Character.digit(c, 10), compressedText.substring(1, 2))) + decompress(compressedText.substring(2)); 
    } 

    return compressedText.charAt(0) + decompress(compressedText.substring(1)); 
} 

正如你所看到的,基本情况是,当压缩String具有小于或等于1(因为你有它在你的程序)的长度。

然后,我们检查第一个字符是否是数字。如果是这样,我们用正确数量的字符替换,并继续递归过程直到达到基本情况。

如果第一个字符不是数字,那么我们简单地追加它并继续。

请记住,这只适用于从1到9的数字;如果您需要更高的价值,请告诉我!

编辑1:如果Collections#nCopies方法过于复杂,这里是等效的方法:

if (Character.isDigit(c)) { 
    StringBuilder sb = new StringBuilder(); 

    for (int i = 0; i < Character.digit(c, 10); i++) { 
     sb.append(compressedText.charAt(1)); 
    } 

    return sb.toString() + decompress(compressedText.substring(2)); 
} 

编辑2:下面是一个使用递归辅助的方法来重复String的方法:

public static String decompress(String compressedText) { 
    if (compressedText.length() <= 1) { 
     return compressedText; 
    } 

    char c = compressedText.charAt(0); 

    if (Character.isDigit(c)) { 
     return repeatCharacter(compressedText.charAt(1), Character.digit(c, 10)) + decompress(compressedText.substring(2)); 
    } 

    return compressedText.charAt(0) + decompress(compressedText.substring(1)); 
} 

public static String repeatCharacter(char character, int counter) { 
    if (counter == 1) { 
     return Character.toString(character); 
    } 

    return character + repeatCharacter(character, counter - 1); 
} 
+0

集合有点太复杂,并且实现for循环可以很容易地输入所需的字母数量。但是,for循环是禁止的,这就是为什么我尝试实现递归方法来返回所需数量的字母。但谢谢你的建议! – Scerzy

+0

你想让我提供一个没有for-loop的解决方案吗? –

+0

那太棒了。我正在尝试以某种方式对其进行编辑,但似乎无法对其进行调整。我再次尝试添加递归(在我的前面的代码中它是它所说的部分(如果num> 0) – Scerzy