水仙花數(Narcissistic Number),又稱阿姆斯特朗數或自戀數。指一個 n 位數,其各位數字的 n 次方之和等於該數本身。最經典的是三位數水仙花數:各位數字立方和等於原數。
例如:153 = 1³ + 5³ + 3³ = 1 + 125 + 27 = 153
public class NarcissisticNumberFinder {
public static void main(String[] args) {
System.out.println("三位數水仙花數有:");
for (int num = 100; num <= 999; num++) {
int hundred = num / 100; // 百位
int ten = (num % 100) / 10; // 十位
int unit = num % 10; // 個位
// 整數運算避免浮點誤差,效率高於 Math.pow()
if (hundred*hundred*hundred + ten*ten*ten + unit*unit*unit == num) {
System.out.println(num + " = " + hundred + "³ + " + ten + "³ + " + unit + "³");
}
}
}
}
三位數水仙花數有:
153 = 1³ + 5³ + 3³
370 = 3³ + 7³ + 0³
371 = 3³ + 7³ + 1³
407 = 4³ + 0³ + 7³
import java.util.Scanner;
public class NarcissisticNumberChecker {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.print("請輸入一個正整數:");
int num = sc.nextInt();
if (isNarcissistic(num)) {
System.out.println(num + " 是水仙花數!");
} else {
System.out.println(num + " 不是水仙花數。");
}
}
/** 通用判斷邏輯:支持任意位數 */
public static boolean isNarcissistic(int num) {
if (num < 0) return false;
String numStr = String.valueOf(num);
int n = numStr.length(); // 位數
int sum = 0;
int temp = num;
while (temp > 0) {
int digit = temp % 10;
sum += Math.pow(digit, n); // 通用 n 次方
temp /= 10;
}
return sum == num;
}
}
// 預計算 0-9 的 n 次方存入數組
int[] powers = new int[10];
for (int i = 0; i < 10; i++) powers[i] = (int) Math.pow(i, n);
// 循環中直接查表:sum += powers[digit];
public static void findAllNarcissistic(int maxDigits) {
for (int n = 3; n <= maxDigits; n++) {
int start = (int) Math.pow(10, n-1);
int end = (int) Math.pow(10, n) - 1;
// 預計算 0-9 的 n 次方
int[] pow = new int[10];
for (int i = 0; i < 10; i++) pow[i] = (int) Math.pow(i, n);
for (int num = start; num <= end; num++) {
int sum = 0, temp = num;
while (temp > 0) {
sum += pow[temp % 10];
temp /= 10;
}
if (sum == num) System.out.println(num + " (位數:" + n + ")");
}
}
}
| 位數 | 水仙花數 |
|---|---|
| 1 | 0-9 (所有個位數) |
| 3 | 153, 370, 371, 407 |
| 4 | 1634, 8208, 9474 |
| 5 | 54748, 92727, 93084 |
| 6 | 548834 |
| 7 | 1741725, 4210818, 9800817, 9926315 |
Math.pow() 返回 double,大數時可能精度丟失,建議整數乘法或預計算數組核心代碼模板:提取位數 → 累加次方和 → 比較。掌握「取位技巧:
%10取末位,/10去末位」與「預計算優化」即可應對所有變體。