我必須使用遞回方法檢查一個數字是否是Armstrong 數字。
public class ArmStrong {
public static void main(String[] args) {
System.out.println(isArm(407, 0, 0));
}
static boolean isArm(int n,int last,int sum) {
if (n <= 0 ) {
if (sum == n) {
return true;
} else {
return false;
}
}
return isArm(n / 10, n % 10,sum last * last * last);
}
}
當我除錯時,在最后一次呼叫isArmwhenn是 4 時,會跳過基本陳述句。
uj5u.com熱心網友回復:
在應用最后一位數字的立方體之前,您的代碼將立即跳轉到答案 ( if (n <= 0)) 。
例如,瑣碎地,讓我們嘗試一下9,這顯然不是阿姆斯壯。
您的代碼將首先檢查 9 是否為 0 - 不是。所以,我們遞回,這將與self(0, 9, 0 0). 下一次運行應該再次遞回,以便sum last*last*last實際上可以完成一些立方體。但它永遠不會到達那里 - n 是 0,所以,你跳進if.
由于您的變數名稱有點泄露,last是指上一次運行中洗掉的數字,但您并沒有將其立方化。
解決方案是在檢查是否為空之前簡單地獲取立方體:n
您的方法應該做的第一件事是
sum = last*last*last;
然后,出現了第二個問題:這正確地計算出您的總和為 407,但是您對照 進行檢查n,這顯然是0- 您在經歷程序中“破壞”了 n。解決這個問題的一種簡單方法是將原始的 n (未受干擾的)作為第四個引數傳遞。我將把它作為練習留給讀者。
uj5u.com熱心網友回復:
盡管@rzwitserloot指出了一個根源于您設計遞回方式的問題,但問題仍未解決。
是的,遞回呼叫“提前一步”計算sum數字,這發生在遞回情況下,給定數字的最左邊的數字不貢獻sum,因為n為零并且遞回達到基本情況. 這是真的,但這不是您需要解決的唯一問題。
這是所謂的自戀數(又名阿姆斯特朗數)的定義:
在數論中,給定數基 bb 中的自戀數(也稱為超完美數字不變數 (PPDI)、阿姆斯特朗數(根據 Michael F. Armstrong)或正完美數)是一個數,它是它的總和自己的位數每提升到位數的次方。
因此,具有硬編碼能力的方法3只能驗證三位數的 Armstrong 數字。它們中只有少數,對于其他有效的 Armstrong 數字,它會產生不正確的結果。
因此,在計算總和之前,您需要知道位數沒有解決方法。如果只想通過遞回來解決問題,也可以遞回計算位數。如果我們采取這條路線,解決方案歸結為實作兩種遞回方法。
這就是它的樣子:
public static boolean isArm(int n) {
return n == getSum(n, getDigitCount(n));
}
public static int getSum(int n, int power) {
return n == 0 ? 0 : (int) Math.pow(n % 10, power) getSum(n / 10, power);
}
public static int getDigitCount(int n) {
return n == 0 ? 0 : 1 getDigitCount(n / 10);
}
main()
public static void main(String[] args) {
System.out.println(isArm(10)); // is not an Armstrong number
System.out.println(isArm(21)); // is not an Armstrong number
System.out.println(isArm(407)); // is an Armstrong number
System.out.println(isArm(153)); // is an Armstrong number
System.out.println(isArm(9)); // is an Armstrong number
}
輸出:
false // 10
false // 21
true // 407
true // 153
true // 9
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/532358.html
標籤:爪哇算法递归
