C++ 使循环更快

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

我想计算一个数是否是一个完美数(和(适当的除数)=数)。所以我所要做的就是得到正确的除数,把它们加起来,看看是不是数字。为此,我使用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 << "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开始,一直到数字的平方根,如果你找到了一个除数do
    sum+=i+number/i
    。自然顺序而不是相反的顺序通常会更快,因为它会立即找到小的除数,从而显著增加和
  • 如果你要解决这个问题的数量非常大,你就不能很快解决它,因为这是一个已知很难有效解决的问题(即没有已知的多项式算法)。因此,没有办法使这个循环比建议的实现快得多(渐近)


    但另一方面,整数因式分解是一个古老且非常重要的问题,因此有一些库使用高级启发式和汇编程序级优化来快速解决它。

    您可以实现一些简单的优化:

  • 只检查素数。你可以用简单的方法快速有效地找到它们。你也可以找到它们一次并保存在文件中。 UPD:小心,在这种实现中很容易引入错误。一种可能的方法是找到所有的除数,将它们保存在数组中,然后迭代所有可能的组合以计算实际的和。可以递归地进行
  • 从2开始,一直到数字的平方根,如果你找到了一个除数do
    sum+=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就像我说的,你只需要把
    除数
    数字/除数
    相加。所以当你访问