2011-11-14 106 views
1

首先這不是功課。只是我在練習。 我試圖遞歸確定「hi」出現在給定字符串中的次數,但在每種情況下,它跳到最後一個else語句以及字符串爲空的事情。有任何想法嗎?Java遞歸計數

基本上, 如果 增量次數由1(串「喜」開頭),並與第二索引後的字符串遞歸跳過了「喜」,它只是計算

否則,如果(String不以「hi」開始並且字符串不爲空) 在第一個索引後遞增字符串,以查看下一次是否以「hi」開頭。

else if(string is empty) Print(「End of text reached」) return count;

public class Practice { 

    public int recur(String str, int counter){ 
     int count=counter; 
     if(str.startsWith("hi")){ 
      count++; 
      recur(str.substring(2),count); 
     } 
     else if((!str.isEmpty())&&(!str.startsWith("hi"))){ 
      recur(str.substring(1),count); 
     } 
     else if(str.isEmpty()){ 
      System.out.println("End of text reached"); 
      return count; 
     } 
     return count; 
    } 

    public static void main(String args[]){ 
     String str="xxhixhixx"; 
     Practice p=new Practice(); 
     System.out.println(p.recur(str, 0)); 
    } 
} 
+2

在字符串處理[wiki](http://en.wikipedia.org/wiki/Recursion_%28computer_science%29#Recursive_procedures)中,有更好的例子可以從遞歸練習開始。 – PeterMmm

+0

我對此有疑問 - 任何呼叫者都可以修改結果,因爲'counter'是外部呼叫的一部分。至少,這應該做'私人',用一個'public'包裝,不包含'計數器'(並且不遞歸)。另一種方法是在遞歸返回期間進行加法。此外,您正在使用'startsWith'檢查,然後將光標移動1 - 'indexOf'有什麼問題(我認爲可用的更好的優化)。 –

回答

2

您沒有使用從recur返回的值。

7

這是練習調試遞歸函數調用的好機會 - 實際上很困難。建議:

  • 使用戰略地位打印報表,以確保參數被正確地改變從一個遞歸調用到下一個
  • 重構案例分析的if語句的順序,以使其更清晰。例如,1)檢查字符串是否爲空(基本情況),2)檢查字符串是否以「hi」開頭,3)全部收集 - 不爲空並且不以「hi」開頭
+0

關於有策略地放置的打印語句,我喜歡將打印與遞歸的深度「對齊」,如下所示:http://stackoverflow.com/questions/7774769/how-do-i-solve-the - 經典揹包算法 - 遞歸地/ 7775224#7775224 – TacticalCoder

+0

@ user988052 - 對於一些遞歸問題可以得心應手,但對於那些涉及樹的問題更是如此。這是一個'線性'遞歸問題,所以它不會有幫助。 –

4

正如@Steve所提到的,您必須使用返回值recur返回。

請參見下面的代碼的修改版本,我還簡化了您的if/else語句:

public int recur(String str, int counter) { 

    if (str.startsWith("hi")) { 
    return recur(str.substring(2), counter+1); 
    } else if (!str.isEmpty()) { 
    return recur(str.substring(1), counter); 
    } else { 
    System.out.println("End of text reached"); 
    return counter; 
    } 
} 

public static void main(String args[]) { 
    String str = "xxhixhixx"; 
    Practice p = new Practice(); 
    System.out.println(p.recur(str, 0)); 
} 
+0

這是正確的解決方案。發生的事情是頂層函數調用正在觸及最後一個返回語句,該語句返回零,因爲它沒有對遞歸調用的返回值做任何事情。 –

+0

哦,我現在記得。謝謝你們的幫助我已經使用遞歸lol已經有一段時間了。 – user1045873

1

你的程序打印「文本結束」是正確的,因爲最後按邏輯就會到達那裏,計數總是爲0的原因是在每次迭代中他們都改變了自己的副本,最後當達到終止條件時(字符串爲空),結果從堆棧中彈出,因此您收到的最終結果是count是0的第一次迭代,因此您必須在每一步都返回由recur返回的值,而不是返回count。

-1
public static int recursive(String givenStr) { 

    int count =0 ; 

    Pattern pattern = Pattern.compile("hi"); 
    Matcher match = pattern.matcher(givenStr); 
    while(match.find()){ 
     System.out.println(match); 
     count++; 
    } 
    return count; 
} 

這將返回的次數「喜」已經出現成字符串

2
public int countHi(String str) { 
     if (str.length() <= 1) { 
     return 0; 
     } 
     int count = 0; 
     if (str.substring(0, 2).equals("hi")) { 
     count = 1; 
     } 
     return count + countHi(str.substring(1)); //substring off 
    } 

這一切確實是遞歸數較大的字符串中的字符串「喜」的數量。其餘的實現應該是小菜一碟,快樂的編碼!