水仙花数(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]