有27個人要喝水,每三個空瓶子可以換一瓶水,問需要買多少瓶水?
完成這道題目時使用了遞歸,發現怎麼也不對,後面找到錯誤,記錄下來。
錯誤版本
public class buyWater {
public static void main(String[] args) {
// TODO Auto-generated method stub
for (int i = 5; i < 27; i++) {
int out = count(i, i);
System.out.println("買 " + i + " 瓶,可以得到 " + out + " 瓶");
if (out >= 27) {
System.out.println("需要買水:" + i + " 瓶");
return;
}
}
}
public static int count(int num, int out) {
int a = num / 3;
out += a;
int b = num - 3 * a;
while((a+b)>=3) out = count(a+b,out);
return out;
}
}
執行結果:
<span style="white-space:pre"> </span>沒有打印輸出,調試發現,程序一直在while循環中,out不斷增加。
分析:
<span style="white-space:pre"> </span>當i=5,執行count,a=1,b=2,滿足while循環,調用count()。執行下一級count(),a=1,b=0,不滿足while條件,return。回到上一級count,a=1,b=2,a、b值沒變,
這就是問題所在了。所以,一直在while循環。
本質在於形參和實參。進入count後,看似仍然使用的a和b,實際上不同的變量,生命週期到本級count執行完(即return)就結束,也不會影響外一級的參數值,所以永遠滿足while循環。
解決方案:
<span style="font-size:12px;">// while((a+b)>=3) out = count(a+b,out);
if(a+b>=3) out=count(a+b, out);</span>
使用if判斷,下一屆count返回時,儘管a、b值沒變,但是if語句不會回去再執行一次。
注意:必須使用
<span style="font-size:12px;"><span style="white-space:pre"> </span>out = count(a+b,out);</span>
<span style="font-size:12px;"><span style="white-space:pre"> </span>不然只</span><span style="font-size: 12px; font-family: Arial, Helvetica, sans-serif;">count(a+b,out);仍然出現out就等於這一級count執行的結果,因爲下一級的out只是個形參,不會改變out的值。</span>