2017-05-04 70 views
1

我有這個任務,需要我解壓縮一個以前壓縮的字符串。這 例子是遞歸解壓一個字符串

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

回答

0

我覺得像這樣的工作:

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