问题描述:
求1到10000之内所有的完数,并表示出来;
样例输出:
6 : 1 2 3;
28 : 1 2 4 7 14;
496 : 1 2 4 8 16 31 62 124 248;
8128 : 1 2 4 8 16 32 64 127 254 508 1016 2032 4064;
共找到 4 个完数;
问题分析:
1、完数:一个数恰好等于其因子之和的数;
2、使用穷举法,穷举1到10000中的所有数num;
3、对穷举的每一个数进行因数分解(所有的因子存入数组arr[]中,以便后序输出)再求和判断(这部分可使用原数(s = num)减去每一个因子,如果减完所有因子之后刚好为零(s == 0)则为完数);
4、按例输出;
完整代码:
#include <iostream>
using namespace std;
int arr[300] = {0};
int code = 0;
void show(int num, int count)
{
cout << num << " : " ;
for (int j(0); j < count; ++j)
{
cout << arr[j];
if (j < count - 1)
cout << " ";
}
cout << endl;
}
int judge(int num)
{
int count = 0;
int s = num;
for (int i(1); i < num / 2 + 1; ++i)
{
if (num % i == 0)
{
arr[count++] = i;
s -= i;
if (s <= 0)
// if ( s < 0)
break;
}
}
if (s == 0)
{
code++;
show(num, count);
}
return code;
}
int main()
{
int perfect_number = 0;
for (int num(2); num < 10000; ++num)
perfect_number = judge(num);
cout << "there have " << perfect_number << " perfect numbers !" << endl;
return 0;
}
代码分析:
main() 用于遍历1-10000的所有数,并调用judge进行判断;
int judge(int num); 用于判断传入的数是否为完数:
23-26行:分离num所有因子,并存入数组arr;此条注意:在这部分数组的大小一定要足够足够大,否则在进行因子分解的时候,遇到不是完数的num是存入因子时会造成数组越界,导致程序出错;
28(29)行:作为是否继续分解的控制条件,如果这个数减他的因子小于或已经等于零后面就不必继续分解,节省计算资源;此条注意:在这部分控制条件虽理论上应是小于等于,但编程时一定不能是小于等于,如果为小于等于会出现:当num循环到24时,分解的因子应有: 1 2 3 4 6 7 8 12;但由于判断条件为<=所以当分解到8时 s-i == 0 已然停止分解,接着程序进入34行判断,此时s == 0 所以24会被当成一个完数输出,这明显是错的,判断条件应为 “<”;
void show(int num, int count);用于格式输出相应的完数和它的因子;传入count便于输出所有所存因子;
结果展示:
(https://img-blog.csdn.net/20160815110231306)
当判断条件为 s <= 0时的结果:
(https://img-blog.csdn.net/20160815110325437)