N位自幂数及打表法优化

题目描述

编写函数,输入数字位数n,输出n位数字中所有的自幂数数。(所谓的自幂数是指一个n位数其各位数字的n次方等于该数本身,例如153是三位自幂数,因为:153=1+125+27。)

代码实现

感谢小白程序进阶之路提供的的代码

#include 
#include 
#include 
int isZiMiShu(int num, int n);
int main()
{
	int n = 0, min = 1;
    printf("请输入数字的位数:");
    scanf("%d", &n);
    //min = pow(10,(n-1));//注意,pow返回值应该是double类型,会出现一定误差,这里的结果不是10^5;
    min = (int)(pow(10,(n-1))+0.5);//四舍五入
	for (int i = min; i < min * 10; i++)//对每个数进行判断
	{
		if(isZiMiShu(i,n) == 1)//如果是自幂数
		{
			printf("%d\n",i);
		}
	}
}
int isZiMiShu(int num, int n)//num为具体的数,n为位数
{
	if(n == 1)
	{
		return 1;
	}
	int StartNum = num;
	int remainder;//余数
	int sum = 0;
	while(StartNum != 0)
	{
		remainder = StartNum % 10;//求余,54748,求余得8
		StartNum /= 10;//54787,除10得5474
		sum += (int)(pow(remainder, n)+0.5);
	}
	if( sum == num )
	{
		return 1;
	}
	else
	{
		return 0;
	}
}

部分打表法优化

部分打表法适用于优化有限的量不大的值固定的复杂的重复的数据,例如该例中的0-9的n次幂。

其思路就是将复杂重复的计算值预先计算存储到数组中,需要用到时查询表格即可。

下面是实现1-5位自幂数的C语言代码:

#include 
#include 
#include 
int pown[5][11]={{0,1,2,3,4,5,6,7,8,9,0},
				{0,1,4,9,16,25,36,49,64,81,10},
				{0,1,8,27,64,125,216,343,512,729,100},
				{0,1,16,81,256,625,1896,2401,4096,6561,1000},
				{0,1,32,243,1024,3125,11376,16807,32768,59049,10000}};
int isZiMiShu(int num, int n);
int main()
{
	int n = 0, min = 1;
    printf("请输入数字的位数:");
    scanf("%d", &n);
    //min = pow(10,(n-1));//注意,pow返回值应该是double类型,会出现一定误差,这里的结果不是10^5;
    min = pown[n-1][10];
    int i;
	for (i = min; i < min * 10; i++)//对每个数进行判断
	{
		if(isZiMiShu(i,n) == 1)//如果是自幂数
		{
			printf("%d\n",i);
		}
	}
}
int isZiMiShu(int num, int n)//num为具体的数,n为位数
{
	if(n == 1)
	{
		return 1;
	}
	int StartNum = num;
	int remainder;//余数
	int sum = 0;
	while(StartNum != 0)
	{
		remainder = StartNum % 10;//求余,54748,求余得8
		StartNum /= 10;//54787,除10得5474
		sum += pown[n-1][remainder];
	}
	if( sum == num )
	{
		return 1;
	}
	else
	{
		return 0;
	}
}

全部打表法优化

警告!此法慎用,老师看见头都给你打歪了

此法思路也很简单,与部分打表法优化部分复杂计算不同的是,全部打表法直接存储答案,需要哪组答案就输出哪组答案(O(1)复杂度,狗头保命

下面是实现1-5位自幂数的C语言代码:

#include 
#include 
#include 
int ans[5][11]={{0,1,2,3,4,5,6,7,8,9,-1},
				{-1},
				{153,370,371,407,-1},
				{8208,9474,-1},
				{48536,54748,92727,93084,-1}};
int main()
{
	int n = 0;
    printf("请输入数字的位数:");
    scanf("%d", &n);
    int i;
	for (i = 0;; i++)
	{
		if(ans[n-1][i] == -1) break;//-1为结束标志 
		printf("%d\n",ans[n-1][i]);
	}
	return 0;
}

你可能感兴趣的:(数据结构与算法,算法)