如何生成 1 到 100 之间的所有完美数字?
完美数是一个正整数,等于它的真除数之和。例如,6(=1+2+3) 是一个完美数。
所以我怀疑弗兰克正在Prolog中寻找答案,是的,它确实闻起来相当家庭作业......
为了好玩,我决定写下我的答案。我花了大约50行。
所以这里是我的谓词的概要。也许它会帮助你思考 Prolog 的方式。
is_divisor(+Num,+Factor)
divisors(+Num,-Factors)
divisors(+Num,+N,-Factors)
sum(+List,-Total)
sum(+List,+Sofar,-Total)
is_perfect(+N)
perfect(+N,-List)
+ 和 - 并不是参数名称的真正组成部分。它们是关于作者期望实例化的文档线索。(NB) "+Foo" 表示您希望 Foo 在调用谓词时有一个值。“-Foo”意味着您希望 Foo 在调用谓词时成为一个变量,并在它完成时给它一个值。(有点像输入和输出,如果这样想有帮助的话)
每当您看到像 sum/2 和 sum/3 这样的一对谓词时,很可能 sum/2 一个就像 sum/3 的一个包装器,它正在执行类似accumulator的操作。
我没有费心让它很好地打印出来。您可以直接在 Prolog 命令行中查询它:
?- perfect(100,L).
L = [28, 6] ;
fail.
我发现 Prolog 谓词可能有帮助的另一件事是,通常有两种。一种是简单地检查某事是否属实。对于这种谓词,您希望其他一切都失败。这些往往不需要递归。
其他人会想要遍历一个范围(数字或列表)并始终返回结果,即使它是 0 或 []。对于这些类型的谓词,您需要使用递归并考虑您的基本情况。
HTH。
注意:这称为“模式”,您实际上可以指定它们,编译器/解释器将强制执行它们,但我个人只是在文档中使用它们。还试图找到有关 Prolog 模式信息的页面,但我找不到好的链接。:(
我不确定这是否是你要找的,但你总是可以打印出“6, 28”......
看起来你需要循环直到 n/2 是 n 的 1/2。将数字相除,如果没有余数,则可以将其包含在总数中,一旦用尽 n 的 1/2,然后检查添加的总数是否 = 您正在测试的数字。
例如:
#include "stdafx.h"
#include "iostream"
#include "math.h"
using namespace std;
int main(void)
{
int total=0;
for(int i = 1; i<=100; i++)
{
for( int j=1; j<=i/2; j++)
{
if (!(i%j))
{
total+=j;
}
}
if (i==total)
{
cout << i << " is perfect";
}
//it works
total=0;
}
return 0;
}