我假設在現實世界中,你只把在跟蹤這樣的(特別是使用一個靜態變量)作爲臨時措施調試,並在投入生產之前刪除代碼。如果你想把它留在生產代碼中,我會尋找一個不同的解決方案。首先,如果您打算爲此使用靜態變量,則需要確保每個遞歸調用在之後恢復其值。這可能是最好做這在finally
塊,以確保恢復總是發生,即使有一個return
隱藏在代碼中的某個地方(或者在例外的情況下):
public static long fibonacci(int n) {
int saveFibCount = fibCount;
fibCount++;
try {
fibCount++;
long result;
if (n == 0 || n == 1) {
result = n;
System.out.printf("fib(%s)-->%s%n", n, result);
} else {
result = fibonacci(n - 1) + fibonacci(n - 2);
System.out.printf("fib(%s)%n", n);
}
return result;
} finally {
fibCount = saveFibCount;
}
}
其次,要獲得這到你的縮進:不幸的是,Java沒有一個內置的方法來返回一串n
空格。你可以寫一個很輕鬆了(在Apache的共享提供或使用方法,我認爲),並利用它們是這樣的:
if (n == 0 || n == 1) {
result = n;
System.out.printf("%sfib(%s)-->%s%n", blanks(4*fibCount), n, result);
} else {
result = fibonacci(n - 1) + fibonacci(n - 2);
System.out.printf("%sfib(%s)%n", blanks(4*fibCount), n);
}
其中blanks(b)
返回b
空白的字符串。您可以使用StringBuilder
創建空字符串,或者類似的東西:
String blanks = String.format("%" + numOfBlanks + "s", "");
[注:根據另一個答案評論,這並不工作,如果numOfBlanks
0]
或者你可以用一個String fibIndent
取代fibCount
,而不是fibCount++
使用
fibIndent += " ";
保存以前的版本之後。
要考慮的另一件事是:如果這是生產代碼,我建議將另一個參數傳遞給遞歸例程,而不是使用靜態變量。試圖用遞歸例程來處理靜態變量,即使在單線程的程序中,也很麻煩且容易出錯。遞歸參數應該是一個值參數或一個不可變的對象,在將它傳遞給下一個調用之前,它將被每個調用複製。在這種情況下,「遞歸深度」(您的fibCount
)可能是參數。我不建議將引用傳遞給所有遞歸調用將共享的對象,因爲這與使用靜態變量(雖然更安全)相比,幾乎具有錯誤傾向。
[注:我花了很多我的職業生涯的一個遞歸下降編譯工作,所以很多這些問題都對我很熟悉]
[最後:我知道這只是練習,但不要使用遞歸來計算斐波那契數。這樣做給你一個指數算法,而不是一個線性算法,因爲它是一個簡單的循環。這是因爲遞歸算法執行大量冗餘工作,計算結果的相同參數的倍數倍。]
來源
2015-01-14 22:31:27
ajb
您不能在格式字符串中將'0'作爲寬度傳遞。另外,OP在當前呼叫的「中綴」打印輸出之後。 – aioobe