[英]Why does this code continue (recursion)?
首先,我想說的是,我知道這是解決我的問題的最糟糕的方法,但是我只想熟悉遞歸。 我想檢查一個序列是否為DNA(因此它只能包含A,T,G或C)。 我的代碼:
public Boolean check(String seq) {
System.out.println(seq);
Boolean correct = true;
Character letter = seq.charAt(seq.length() - 1);
if ("ATGC".contains(letter.toString())) {
if (seq.substring(0, seq.length() - 1).length() > 0) {
check(seq.substring(0, seq.length() - 1));
}
} else {
correct = false;
}
System.out.println(seq + " " + correct);
return correct;
}
但是,當我運行代碼時,更改correct = false
后它將繼續運行。 為了清楚起見,我將粘貼打印語句的輸出:
ATXGCTGC
ATXGCTG
ATXGCT
ATXGC
ATXG
ATX
ATX false
ATXG true
ATXGC true
ATXGCT true
ATXGCTG true
ATXGCTGC true
返回的布爾值為true
,但是在ATX false
后,代碼應該已停止。 出了什么問題以及如何解決此問題?
沒關系。 您所謂的“保持運行狀態”就是遞歸的工作方式。 如果您看過初始電影,可以作為一個比喻來幫助您。
函數會多次調用自身(您的第一個println
語句對此進行了標記),然后在某種程度上滿足了遞歸結束條件后,函數會將執行返回到調用堆棧幀(這是第二個println
捕獲的幀)。
使用“ AA”的簡單示例:
PS您遇到的一個問題是忽略該函數的返回結果。
您放棄對check
的遞歸調用的結果。 因此,即使支票返回false
,信息也會丟失。 並且由於在其中調用check
的分支永遠不會設置correct
因此它將保留其初始化值( true
)。
據我一眼就能看出,解決方案就像分配correct
的check
返回值一樣簡單。
您沒有檢查它是否返回false
。 您需要創建一個if語句,以在check()
返回false
時結束方法
只需打電話
check(seq.substring(0, seq.length() - 1));
您正在執行所需的操作,但是當遞歸返回時,該方法將繼續運行(如您在輸出中字符串“增長”時所見)。
如果增加使用
return check(seq.substring(0, seq.length() - 1));
或者可能
correct = check(seq.substring(0, seq.length() - 1));
您可能會得到所需的輸出。 您可以使用調試器來診斷哪個更有意義
遇到錯誤字符時,您沒有條件終止。 適當的遞歸方法如下:
private static Set<Character> LEGAL_CHARS =
new HashSet<>(Arrays.asList('A', 'T', 'G', 'C'));
public boolean check(String seq) {
if (seq.isEmpty()) {
return true;
}
if (!LEGAL_CHARS.contains(seq.charAt(0))) {
return false;
}
return check(seq.substring(1));
}
您只需要更改線
if (seq.substring(0, seq.length() - 1).length() > 0) { check(seq.substring(0, seq.length() - 1)); }
if (seq.substring(0, seq.length() - 1).length() > 0) { check(seq.substring(0, seq.length() - 1)); }
到
if (seq.substring(0, seq.length() - 1).length() > 0) { return check(seq.substring(0, seq.length() - 1)); }
if (seq.substring(0, seq.length() - 1).length() > 0) { return check(seq.substring(0, seq.length() - 1)); }
這會使您的檢查結果返回上一級遞歸函數,
最后是理想的結果。
為什么需要返回檢查功能?
當您在if check內部調用check函數時,會創建一個新的遞歸調用,該調用及其變量在堆棧中排隊。 當它返回結果時,您只是忽略了它(沒有存儲結果)。 要使用最低級別的遞歸函數的值,您需要將其值傳遞回其父遞歸調用。如此一來,您最終得到結果。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.