找自幂数的逐步优化算法

	自幂数是指一个 n 位数,它的每个位上的数字的 n 次幂之和等于它本身。(例如:当n为3时,有1^3 + 5^3 + 3^3 = 153,153即是n为3时的一个自幂数)

自幂数包括:独身数、水仙花数、四叶玫瑰数、五角星数、六合数、北斗七星数、八仙数、九九重阳数、十全十美数 。
下面分析怎样找出自幂数的算法:
1:首先要能判断一个自幂数
(这里面可以分为几个函数
1.找出数字的位数
2.给一个算次方的函数)
2:给定范围,查找自幂数
说到这里有的小朋友可能特别疑惑了,为神魔要自造一个算次方的函数呢?
C语言的math.h库里面不是有pow()函数直接调用吗?
请注意本文章的标题,我们要优化,优化,优化,我们要给一个更快的方法,嘿哈。
先给出我第一次写出来的代码

#include <stdio.h>
#include <time.h>
#include "./include/mec.h"
boolean isSelfPower(int num);
int intLen(int num);
int intPow(int a, int p);
boolean isSelfPower(int num) {
	int cnt;
	int sum;
	int n;

	cnt = intLen(num);

	sum = 0;
	for (n = num; n && sum <= num; n /= 10) {
		sum += intPow(n % 10 ,cnt);
	}

	return sum == num;
}

int main() {
	int num;
	int maxNum;
	long startTime;
	long endTime;
	long deltaTime;

	printf("输入最大范围:");
	scanf("%d", &maxNum);

	startTime = clock();
	for (num = 0; num < maxNum; num++) {
		if (isSelfPower(num)) {
			printf("%d是自幂数\n", num);
		}
	}
	endTime = clock();
	deltaTime = endTime - startTime;
	printf("耗时:%ld.%03lds\n", deltaTime / CLOCKS_PER_SEC, deltaTime % CLOCKS_PER_SEC);

	return 0;
}


int intLen(int num) {
	int cnt = 0;

	if (num <= 0) {
		return 1;
	}

	while (num) {
		cnt++;
		num /= 10;
	}

	return cnt;
}

int intPow(int a, int p) {
	int sum = 1;
	int i;

	for (i = 0; i < p; i++) {
		sum *= a;
	}

	return sum;
}

 



程序运行到这里,已经卡住了,头疼,头疼
程序运行到这里,已经卡住了,头疼,头疼,这种算法可能
我们分析一下,计算长度能不能不用循环呢,我们这样想,可以定一个a[10]数组,a[0]为0,a[1]为10,a[2]为100,若最大范围数组小于a[i-1]大于a[i]则位数为i,这样不用循环,节省了时间,就很简单的判断了数字的位数!
我们再来看一下我们的,程序优化后的速度;
看,我们的程序又快了一点哦
可是他还不够快,我还想更快!!!!!
我们直接给出一个二维数组,将数字的1到10次方的数值存到一个数组里面。
这样直接在数组里面找,不用再来循环叠加,再乘计算!

这样我们来看看最终的运行耗时!
是不是有了很可观的效果了哈哈哈
我们在最后来给出最后完全的代码!

#include <stdio.h>
#include <time.h>

#include "./include/mec.h"

const int powValue[][10] = {
	0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
	0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
	0, 1, 2*2, 3*3, 4*4, 5*5, 6*6, 7*7, 8*8, 9*9,
	0, 1, 2*2*2, 3*3*3, 4*4*4, 5*5*5, 6*6*6, 7*7*7, 8*8*8, 9*9*9,
	0, 1, 2*2*2*2, 3*3*3*3, 4*4*4*4, 5*5*5*5, 6*6*6*6, 7*7*7*7, 8*8*8*8, 9*9*9*9,
	0, 1, 2*2*2*2*2, 3*3*3*3*3, 4*4*4*4*4, 5*5*5*5*5, 6*6*6*6*6, 7*7*7*7*7, 8*8*8*8*8, 9*9*9*9*9,
	0, 1, 2*2*2*2*2*2, 3*3*3*3*3*3, 4*4*4*4*4*4, 5*5*5*5*5*5, 6*6*6*6*6*6, 7*7*7*7*7*7, 8*8*8*8*8*8, 9*9*9*9*9*9,
	0, 1, 2*2*2*2*2*2*2, 3*3*3*3*3*3*3, 4*4*4*4*4*4*4, 5*5*5*5*5*5*5, 6*6*6*6*6*6*6, 7*7*7*7*7*7*7, 8*8*8*8*8*8*8, 9*9*9*9*9*9*9,
	0, 1, 2*2*2*2*2*2*2*2, 3*3*3*3*3*3*3*3, 4*4*4*4*4*4*4*4, 5*5*5*5*5*5*5*5, 6*6*6*6*6*6*6*6, 7*7*7*7*7*7*7*7, 8*8*8*8*8*8*8*8, 9*9*9*9*9*9*9*9,
	0, 1, 2*2*2*2*2*2*2*2*2, 3*3*3*3*3*3*3*3*3, 4*4*4*4*4*4*4*4*4, 5*5*5*5*5*5*5*5*5, 6*6*6*6*6*6*6*6*6, 7*7*7*7*7*7*7*7*7, 8*8*8*8*8*8*8*8*8, 9*9*9*9*9*9*9*9*9,
};


boolean isSelfPower(int num);
int intLen(int num);
int intPow(int a, int p);

int intPow(int a, int p) {
	return powValue[p][a];
}


int intLen(int num) {
	if (num < 0) {
		return 0;
	}
	if (num >= 100000000 && num < 1000000000) {
		return 9;
	}
	if (num >= 10000000 && num < 100000000) {
		return 8;
	}
	if (num >= 1000000 && num < 10000000) {
		return 7;
	}
	if (num >= 100000 && num < 1000000) {
		return 6;
	}
	if (num >= 10000 && num < 100000) {
		return 5;
	}
	if (num >= 1000 && num < 10000) {
		return 4;
	}
	if (num >= 100 && num < 1000) {
		return 3;
	}
	if (num >= 10 && num < 100) {
		return 2;
	}
	return 1;
}


boolean isSelfPower(int num) {
	int cnt;
	int sum;
	int n;

	cnt = intLen(num);

	sum = 0;
	for (n = num; n && sum <= num; n /= 10) {
		sum += intPow(n % 10 ,cnt);
	}

	return sum == num;
}

int main() {
	int num;
	int maxNum;
	long startTime;
	long endTime;
	long deltaTime;

	printf("输入最大范围:");
	scanf("%d", &maxNum);

	startTime = clock();
	for (num = 0; num < maxNum; num++) {
		if (isSelfPower(num)) {
			printf("%d是自幂数\n", num);
		}
	}
	endTime = clock();
	deltaTime = endTime - startTime;
	printf("耗时:%ld.%03lds\n", deltaTime / CLOCKS_PER_SEC, deltaTime % CLOCKS_PER_SEC);

	return 0;
}


/*int intLen(int num) {
	int cnt = 0;

	if (num <= 0) {
		return 1;
	}

	while (num) {
		cnt++;
		num /= 10;
	}

	return cnt;
}
*/
/*
int intPow(int a, int p) {
	int sum = 1;
	int i;

	for (i = 0; i < p; i++) {
		sum *= a;
	}

	return sum;
}
*/



嘿嘿,这样就结束啦,如果你们能给出一个更加快速,时间复杂度更低的算法呢,欢迎留言,讨论,互相关注
后面还会提一些比较有意思的算法哦!!!

  • 5
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值