完全数PerfectNumber

本文介绍了求解10000以内的完全数的改进算法,通过避免重复计算和优化存储方式,提高了效率并节省了空间。同时,对比原始算法,详细解释了改进之处,包括如何利用数学特性减少循环次数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

<span style="font-size:24px;color:#ff0000;">/*
	完全数(Perfect number),又称完美数或完备数,是一些特殊的自然数。
	它所有的真因子(即除了自身以外的约数)的和(即因子函数),恰好等于它本身。
	例如,第一个完全数是6,它有约数1、2、3、6,除去它本身6外,其余3个数相加,1+2+3=6。
	第二个完全数是28,它有约数1、2、4、7、14、28,除去它本身28外,其余5个数相加,1+2+4+7+14=28。
	编程求10000以内的完全数。
*/
#include<stdio.h>
#define RANGE 10000         //查找的最大范围
#define STRLENTH 100        //存放真因子的数组的范围
bool Is_perfect_num(int n)
{
	int array[STRLENTH];//存放真因子的数组
	int count = 0;      //真因子的个数
	int total = 0;      //真因子相加的和

/*将真因子存放于数组中*/
	for(int i=1;i<n;++i)
	{
		if(n%i == 0)
		{
			array[count++] = i;
	//		count++;
		}
	}
/*计算所有真因子的和*/
	for(i=0;i<count;++i)
	{
		total += array[i];
	}
//	if(total == n)
//		return true;//如果是完全数,返回ture否则返回false
//	else 
//		return false;
	return (total == n);

}

int main()
{
	for(int i=1;i<=RANGE;++i)
	{
		if(Is_perfect_num(i))
			printf("%d\n",i);
	}
	return 0;
}
</span>


上述代码,效率不高(求约数时,挨个判断1 --> n-1),且浪费存储空间(用到数组)

改进版代码如下:


/*
	6: (1,6)      (2,3)---->开始重复--->(3,2)
	12:(1,12)(2,6)(3,4)---->开始重复--->(4,3)(6,2)
	即:
	n=a*b(a<=b)  36=6*6---->a,b是n的真因子------>>>>当b>a时开始重复
*/
#include<stdio.h>
#define RANGE 10000     //查找的最大范围
bool Is_perfect_num(int n)
{
	int total = 0;  //因子(约数)相加的和
	int a = 1;      //第一对因子(约数)
	int b = n;
	
	while(a < b)    //未重复
	{
		if(n%a == 0)
		{
			total += a+b;//a,b是n的因子,加入到total中
		}
		a++;//为下一次判断做准备
		b = n/a;
	}

/*a,b相等的情况,只加一次,所以不能放入上面的while循环中,得单独考虑*/
	if(a == b && a*b == n)
	{
		total += a;
	}
/*注意已下return语句,比用if else简洁多了,本身就是个布尔类型*/
	return (total-n == n);//求所有真因子的和,所以将本身减去
}

int main()
{
	for(int i=1;i<=RANGE;++i)
	{
		if(Is_perfect_num(i))
			printf("%d\n",i);
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值