大佬教程收集整理的这篇文章主要介绍了为什么我们要迭代到 root(n) 来检查 n 是否是一个完美数,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
在检查数字 n 是否完美时,为什么我们要检查直到 (n) 的平方根?
也可以解释下面循环中的if条件
for(int i=2;i<sqrt(n);i++)
{
if(n%i==0)
{
if(i==n/i)
{
sum+=i; //Initially,sum=1
}
else
{
sum+=i+(n/i);
}
}
}
根据number theory,任何数至少有2个约数(1,数本身),如果数A是数B的约数strong>,那么数 B / A 也是数 B 的约数。现在考虑一对数字X、Y,使得X * Y == B。如果X == Y == sqrt(B),那么很明显X,Y 。如果我们试图增加Y,那么我们必须减少X,这样他们的乘积仍然等于B。所以结果证明,在任何一对数字 X,Y 中,在产品中给出 B,至少有一个数字是 。因此,只需找到 的所有 B 的除数就足够了。
至于循环条件,那么sqrt(B)是数B的除数,但是我们B / sqrt(B) > 也是一个除数,它等于sqrt(B),为了不把这个除数加两次,我们写了这个if(但是你要明白它永远不会被执行,因为您的循环最多只有 sqrt(n)
)。
代码使用了一次找到两个因数的技巧,因为如果 i
除以 n
那么 n/i
也会除以 n,并且通常将它们都相加(else-clause) .
但是,您遗漏了代码中的错误:它在 i<sqrt(n)
时循环,但有处理 i*i=n
的代码(then 子句 - 它应该只添加一次 i
那种情况),这是没有意义的,因为这两种情况不能同时成立。
所以循环应该是 <=sqrt(n)
,即使没有完全平方数。 (至少我还没有看到任何平方完全数,如果有一个简单的证据证明它们根本不存在,我也不会感到惊讶。)
根据数论,这很简单:
这就是为什么您只需要从 1
-> sqrt(n)
进行检查。但是,您的代码没有到达与 i==n/i
相同的子句 i == sqrt(n)
,因此如果 N 是一个完美的平方,则不会计算 sqrt(n)
。
#include <iostream>
#include <cmath>
using namespace std;
int main()
{
int n; cin >> n;
int sum = 1;
for(int i=2;i<sqrt(n);i++)
{
if(n%i==0)
{
if(i==n/i) { sum+=i; }
else { sum+=i+(n/i); }
}
}
cout << sum;
}
输入:9
输出:1
如您所见,完全忽略了因子 3 = sqrt(9)
。为避免这种情况,请使用 i <= sqrt(n)
,或为避免使用 sqrt()
,请使用 i <= n/i
或 i*i <= n
。
编辑:
正如@HansOlsson 和@Bathsheba 提到的,不存在完全数的奇数平方(很容易证明,甚至没有已知的奇数完全数),对于偶数平方,有一个证明here。因此在这种特殊情况下可以忽略 sqrt(n)
问题。
然而,在其他情况下,当您只需要迭代这些因素时,可能会出现一些错误。最好从一开始就使用正确的方法,而不是在将其用于其他用途时尝试追踪错误。
相关帖子:Why do we check up to the square root of a prime number to determine if it is prime?
以上是大佬教程为你收集整理的为什么我们要迭代到 root(n) 来检查 n 是否是一个完美数全部内容,希望文章能够帮你解决为什么我们要迭代到 root(n) 来检查 n 是否是一个完美数所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。