水仙花數(Narcissistic number)也被稱為超完全數字不變數(pluperfect digital invariant, PPDI)、自戀數、自冪數、阿姆斯壯數或阿姆斯特朗數(Armstrong number),水仙花數是指一個 3 位數,它的每個位上的數字的 3次冪之和等於它本身(例如:1^3 + 5^3+ 3^3 = 153)。 [來自百度百科]
之前寫過一個求固定位數的水仙花數的方法,說固定位數的意思是,不能隨便指定N的值,而是只算出了3位和4位的長度,因為實現方法是多少位數就用多少個for循環來計算,雖然用最笨的方法算出了幾位水仙花數,但這個算法基本就是不可用的,因為沒有找到一個合適的遍歷方法來循環遍歷一個事先未知的多位數,所以努力了很久一直沒有想到真正解決隨意指定長度的水仙花數的找尋方法。
這幾日閑來無事,嘗試了很久,終於完成了計算任意位(任意位只是指在int類型上限范圍內的計算,超過int型上限的沒有解決)水仙花數的算法,在這里寫出來分享給大家,也供自己日后參考。
注:嚴格說來,只有3位才稱之為水仙花數,但我們這里指的是擴展意義的水仙花數,即任意位數的自冪數,即一個多位數,假設為N位,則自冪數的意思是該多位數的每一位數的N次冪之和等於它自己,也即:
a^N+b^N+...+n^N = ab...n
1 #include<stdio.h>
2 #include<stdlib.h>
3 #include<malloc.h>
4
5 int getvalue(int* src, int n)//求多位數本身的值
6 { 7 int i = 0; 8 int wei; 9 int total = 0; 10 int weisu = 1; 11
12 wei = n-1; 13 while(1) 14 { 15 if(wei) 16 { 17 weisu *= 10; 18 wei--; 19 continue; 20 } 21 else
22 { 23 total += (src[i]*weisu); 24 i++; 25 wei = n-1-i; 26 weisu = 1; 27 if(wei<0) 28 { 29 break; 30 } 31 } 32 } 33 return total; 34 } 35
36 int getsum(int *src, int n)//求各位自冪后的和
37 { 38 int i = 0; 39 int j = 0; 40 int sum = 0; 41 int weishu = 1; 42
43 for(i=0; i<n; i++) 44 { 45 for(j=0; j<n; j++) 46 { 47 weishu *= src[i]; 48 } 49 sum += weishu; 50 weishu = 1; 51 } 52 return sum; 53 } 54
55 int sxhx(int n) 56 { 57 int total = 0; 58 int val = 0; 59 int i; 60 int cur = n-1; 61 int *ptr = NULL; 62
63 ptr = (int*)malloc(sizeof(int)*n); 64 ptr[0] = 1; 65 for(i=1;i<n;i++)//初始化一個數從100..到999...,比如4位數是從1000到9999
66 { 67 ptr[i] = 0; 68 } 69 printf("%d wei shuixianhuasu is:\n", n); 70
71 while(1) 72 { 73 total = getsum(ptr, n); 74 val = getvalue(ptr, n); 75 if(total == val) 76 { 77 printf("%d is shuixianhuasu\n", val); 78 } 79 ptr[cur]++; 80 while(ptr[cur] >9) 81 { 82 ptr[cur] = 0; 83 cur = cur-1; 84 if(cur<0) 85 { 86 break; 87 } 88 else
89 { 90 ptr[cur]++; 91 } 92 } 93 if(cur<0) 94 { 95 break; 96 } 97 cur = n-1; 98 } 99 return 0; 100 } 101
102 int main() 103 { 104 int wei = 8;//求8位的水仙花數
105 sxhx(wei); 106 return 0; 107 }
[轉自本人網易博客,原作時間:2013-09-13 13:37:30]