C++ 使循环更快
我想计算一个数是否是一个完美数(和(适当的除数)=数)。所以我所要做的就是得到正确的除数,把它们加起来,看看是不是数字。为此,我使用For循环:C++ 使循环更快,c++,loops,optimization,C++,Loops,Optimization,我想计算一个数是否是一个完美数(和(适当的除数)=数)。所以我所要做的就是得到正确的除数,把它们加起来,看看是不是数字。为此,我使用For循环: cin >> number; sum = 1; for (int i = number/2; i > 1; --i) { if (number % i == 0) { sum = sum + i; } if (sum > number) {break;} } if (sum == number) {cout
cin >> number;
sum = 1;
for (int i = number/2; i > 1; --i) {
if (number % i == 0) {
sum = sum + i;
}
if (sum > number) {break;}
}
if (sum == number) {cout << "perfect!" << endl;}
cin>>编号;
总和=1;
对于(int i=number/2;i>1;--i){
如果(编号%i==0){
sum=sum+i;
}
如果(和>数){break;}
}
如果(sum==number){cout如果你真的想计算这个循环的时间并测试大数,首先你可以试着消除素数,然后用它来找到这个数的除数
如果你测试小数字,你应该从1开始迭代,只测试数字直到数字的平方根()。如果你真的想缩短这个循环的时间并测试大数字,首先你可以尝试消除素数。然后使用查找数字的除数
如果测试较小的数字,则应从1开始迭代,只测试数字直到数字的平方根()。您可以通过以下方式获得非常大的改进:
cin >> number;
sum = 1;
for (int i = sqrt(number); i > 1; --i) {
if (number % i == 0) {
sum += i + (number / i);
}
if (sum > number) {break;}
}
if (sum == number) {cout << "perfect!" << endl;}
cin>>编号;
总和=1;
对于(整数i=sqrt(数字);i>1;--i){
如果(编号%i==0){
总和+=i+(个数/i);
}
如果(和>数){break;}
}
如果(sum==number){cout您可以通过以下方式获得非常大的改进:
cin >> number;
sum = 1;
for (int i = sqrt(number); i > 1; --i) {
if (number % i == 0) {
sum += i + (number / i);
}
if (sum > number) {break;}
}
if (sum == number) {cout << "perfect!" << endl;}
cin>>编号;
总和=1;
对于(整数i=sqrt(数字);i>1;--i){
如果(编号%i==0){
总和+=i+(个数/i);
}
如果(和>数){break;}
}
如果(sum==number){cout您可以实现一些简单的优化:
只检查素数。你可以用简单的方法快速有效地找到它们。你也可以找到它们一次并保存在文件中。
UPD:小心,在这种实现中很容易引入错误。一种可能的方法是找到所有的除数,将它们保存在数组中,然后迭代所有可能的组合以计算实际的和。可以递归地进行
从2开始,一直到数字的平方根,如果你找到了一个除数dosum+=i+number/i
。自然顺序而不是相反的顺序通常会更快,因为它会立即找到小的除数,从而显著增加和
如果你要解决这个问题的数量非常大,你就不能很快解决它,因为这是一个已知很难有效解决的问题(即没有已知的多项式算法)。因此,没有办法使这个循环比建议的实现快得多(渐近)
但另一方面,整数因式分解是一个古老且非常重要的问题,因此有一些库使用高级启发式和汇编程序级优化来快速解决它。您可以实现一些简单的优化:
只检查素数。你可以用简单的方法快速有效地找到它们。你也可以找到它们一次并保存在文件中。
UPD:小心,在这种实现中很容易引入错误。一种可能的方法是找到所有的除数,将它们保存在数组中,然后迭代所有可能的组合以计算实际的和。可以递归地进行
从2开始,一直到数字的平方根,如果你找到了一个除数dosum+=i+number/i
。自然顺序而不是相反的顺序通常会更快,因为它会立即找到小的除数,从而显著增加和
如果你要解决这个问题的数量非常大,你就不能很快解决它,因为这是一个已知很难有效解决的问题(即没有已知的多项式算法)。因此,没有办法使这个循环比建议的实现快得多(渐近)
但另一方面,整数因式分解是一个古老且非常重要的问题,因此有一些库使用高级启发式和汇编程序级优化来快速解决它。有一些方法可以优化它
循环sqrt(N)次,而不是N/2次。(O(sqrt(N))
使用预生成的数组。(O(0)?)
使用thread
s的魔力。(取决于)
用筛子除去素数。(O(N)~O(N^2))
有一些方法可以优化这一点
循环sqrt(N)次,而不是N/2次。(O(sqrt(N))
使用预生成的数组。(O(0)?)
使用thread
s的魔力。(取决于)
用筛子除去素数。(O(N)~O(N^2))
当number%i==0
时,number%(number/i)==0
一个可能的技巧-从number/2
开始,而不是从sqrt(number)开始
。注意,如果i
是一个除数,那么number/i
也是一个除数,所以你只需要访问两者中较小的一个。@nwp不是这样,或者至少不是很简单。28=1+2+4+7+14
是一个完美的数字,但4不是素数。更简单的技巧是对所有完美的数字进行硬编码。只有一个适合一个32位的整数,再加上几个64位的整数。@Nils\S就像我说的,你只需要把除数和数字/除数相加。所以当你访问2时,你就加上2和3。当数字%I==0
,数字%(数字/I)==0
t一个可能的技巧-从number/2开始,而不是从sqrt(number)开始
。注意,如果i
是一个除数,那么number/i
也是一个除数,所以你只需要访问两者中较小的一个。@nwp不是这样,或者至少不是很简单。28=1+2+4+7+14
是一个完美的数字,但4不是素数。更简单的技巧是对所有完美的数字进行硬编码。只有一个适合一个32位整数,再加上几个64位整数。@Nils\S就像我说的,你只需要把除数
和数字/除数
相加。所以当你访问