2016-12-13 67 views
1

給定一個字符串,遞歸計算(無循環)字符串中小寫'x'字符的數量。Java在指定的字符串中計算x的數量

countX( 「xxhixx」)→4

countX( 「xhixhix」)→3

countX( 「HI」)→0

我嘗試:

public int countX(String str) { 
    int sum = 1; 
    if(str.length()-1==0){ 
    return sum; 
    } 
    else{ 
    if(str.charAt(0)=='x'){ 
     return sum+countX(str.substring(1)); 

    } 
    if(str.charAt(0)!='x'){ 
     return countX(str.substring(1)); 
    } 
    } 
} 

我收到以下錯誤消息:This method must return a result of type int. 甚至不知道我的基本情況是否正確。任何提示?

+2

您沒有返回條件之外。 – KyleKW

+4

*你可以知道'=='和'!='是互斥的,但編譯器不能。使用'else'而不是'!='。 – chrylis

+0

@chrylis:嚴格來說,互相排斥在這裏並不重要。重要的是,這兩個ifs耗盡了所有可能性。它們可以重疊 - 因此不會相互排斥 - 並且仍然可以。相反,它們可能是相互排斥的,但未能涵蓋所有可能性。 – NPE

回答

3

它是通過函數每個代碼路徑必須返回值的要求,編譯器是一個有點過於迂腐你:

if(str.charAt(0)=='x'){ 
    return sum+countX(str.substring(1)); 
} 
if(str.charAt(0)!='x'){ 
    return countX(str.substring(1)); 
} 
// <--- there's no return value here 

按理說,編譯器可能圖指出,這兩個if語句排除了所有可能性,但事實並非如此。幫助編譯器一起

一種方式是通過改寫兩個IFS作爲單一的if-else:

if(str.charAt(0)=='x') { 
    return sum+countX(str.substring(1)); 
} else { 
    return countX(str.substring(1)); 
} 
+0

任何想法如何擺脫這個'int sum'?因爲代碼只有在我放入的字符串中有任何x時才起作用。 – DerDieDasEhochWas

+0

@DerDieDasEhochWas:仔細考慮一下你的基本情況。您當前的代碼永遠不會返回零。另外,它不能正確處理長度爲1的字符串。我想這些提示可以解決它。 :-) – NPE

+0

我明白了。非常感謝。 :) – DerDieDasEhochWas

0

並非所有的代碼路徑有回報(從一個愚蠢的編譯器點)。在一開始總結似乎也是錯誤的。試想一下:

public int countX(String str) { 
    if(str.length()==0){ 
    return 0; 
    } else if(str.charAt(0)=='x'){ 
    return 1 + countX(str.substring(1)); 
    } else { 
    assert str.charAt(0)!='x'; 
    return countX(str.substring(1)); 
    } 
} 

或者:

public int countX(String str) { 
    if(str.length()==0){ 
    return 0; 
    } 
    if(str.charAt(0)=='x'){ 
    return 1 + countX(str.substring(1)); 
    } 
    assert str.charAt(0)!='x'; 
    return countX(str.substring(1)); 
} 

方法很多炒魚:

public int countX(String str) { 
    return str.isEmpty() ? 0 : (
    (str.charAt(0)=='x' ? 1 : 0) 
    + countX(str.substring(1)) 
); 
} 

要更加簡潔,不易閱讀?

public int countX(String str) { 
    return str.isEmpty()?0:countX(str.substring(1))+str.charAt(0)=='x'?1:0; 
} 

對不起,我正在開心朝着代碼混淆玩具趨勢。

+0

編號1和2不適用於所有情況。 3號確實有效,但我從來沒有聽說過斷言。 4號令我害怕,所以我沒有測試它。 – DerDieDasEhochWas

+0

數字1和2檢查字符串長度不正確,固定。我試圖從原來的代碼中反覆取出,然後顯示其他選項。只是我輸入的例子 - 你真的運行過嗎? –

+0

關於斷言:作爲程序員,我們知道在特定條件下某個條件在邏輯上應該是真的。我們可以通過某種方式捕獲這些知識,並通過'assert'語句在調試模式下進行檢查。 assert之後的表達式必須評估爲true,並且只有在啓用斷言(通常是調試/開發時間,但不是生產)時纔會運行。 –

0

這樣的事情應該這樣做。

public int countX(String str) { 
    int sum = 0; 
    if(str.length()-1!=0){ 
    sum = countX(str.substring(1)); 
    if(str.charAt(0)=='x'){ 
     sum += 1; 
    } 
    } 
    return sum; 
} 

你的問題是,在某些情況下,沒有回報。爲了避免這種 一種方式是通過在你的方法結束使用單一的返回指令,或者你可以簡單地添加一些其他情況下,你的代碼是這樣的:

[...] 
    else{ 
    if(str.charAt(0)=='x'){ 
     return sum+countX(str.substring(1)); 
    }else{ 
     return countX(str.substring(1)); 
    } 
    } 
    [...] 
1

如何使用告吹,而不是明確有if/else,在某些情況下可能會混淆編譯器

public static int countX(final String str) { 
    //base case 
    if(str.length() == 0) { 
     return 0; 
    } 
    else if(str.length() == 1) { 
     return str.charAt(0) == 'x' ? 1 : 0; 
    } 
    //recursive step 
    return str.charAt(0) == 'x' ? 1 + countX(str.substring(1)) : countX(str.substring(1)); 
} 
+0

如果你傳遞一個空字符串到這個版本,壞的事情將會發生,因爲基本情況至少假設一個字符。 –

+0

謝謝。非常好。但是如果我把空串放進去呢?如果我這樣做,我會得到一個索引超出範圍的例外。 – DerDieDasEhochWas

+0

好的 - 我更新了答案。 –