C程序运行速度惊人的慢

时间:2013-08-17 18:48:39

标签: c performance compiler-construction

我在C中编写的一个简单程序需要花费半个多小时才能运行。我很惊讶C运行需要这么长时间,因为我可以在互联网上找到C(除了C ++或Java)是更快的语言之一。

// this is a program to find the first triangular number that is divisible by 500 factors

int main()
{
    int a; // for triangular num loop
    int b = 1; // limit for triangular num (1+2+3+......+b)
    int c; // factor counter
    int d; // divisor
    int e = 1; // ends loop
    long long int t = 0; // triangular number in use

    while( e != 0 )
    {   
        c = 0;

        // create triangular number t
        t = t + b;
        b++;

        // printf("%lld\n", t); // in case you want to see where it's at
        // counts factors
        for( d = 1 ; d != t ; d++ )
        {       
            if( t % d == 0 )
            {
                c++;
            }       
        }

        // test to see if condition is met
        if( c > 500 )
        {
            break;  
        }
    }

    printf("%lld is the first triangular number with more than 500 factors\n", t);

    getchar();
    return 0;
}

当然程序会运行大量数据,但它们都没有保存,只是经过测试和传递。

我在Windows 8上使用Tiny C编译器。

是否有这么慢的原因?什么是更快的方法来实现相同的结果?

谢谢!

5 个答案:

答案 0 :(得分:2)

你正在迭代你不需要的大量数字。根据定义,正因子是可以乘以另一个以获得所需产品的任何整数。

Ex: 12 = 1*12, 2*6, and 3*4

决定因素时不考虑乘法的顺序。换句话说,

Ex: 12 = 2*6 = 6*2

订单无关紧要。 2和6是因子一次

平方根是一个单独的单一产品的分解单元。所有其他人都是成对的,我希望这很清楚。鉴于此,您可以通过执行以下操作来显着加快代码速度:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

// this is a program to find the first triangular number that is divisible by 500 factors

int main()
{
    int c = 0;                  // factor counter
    long long int b = 0;        // limit for triangular num (1+2+3+......+b)
    long long int d;            // divisor
    long long int t = 0;        // triangular number in use
    long long int r = 0;        // root of current test number

    while (c <= 500)
    {
        c = 0;

        // next triangular number
        t += ++b;

        // get closest root.
        r = floor(sqrt(t));

        // counts factors
        for( d = 1 ; d < r; ++d )
        {
            if( t % d == 0 )
                c += 2;  // add the factor *pair* (there are two)
        }
        if (t % r == 0)  // add the square root if it is applicable.
            ++c;
    }

    printf("%lld is the first triangular number with more than 500 factors\n", t);
    return 0;
}

运行此on IDEOne.com只需不到两秒钟的时间才能提出以下内容:

<强>输出

76576500 is the first triangular number with more than 500 factors

我希望这会有所帮助。 (我认为这是正确的答案)。如果您感兴趣的话,肯定会有更有效的方法(see here对于一些破坏者),但是按照您的代码构思并看看我们可以采取多少措施是这个答案的目标。

最后,根据您的输出消息,它会找到超过500个因子(即501或更多)的第一个数字。您在该文件顶部的评论表示您正在寻找500或更多的第一个号码,这与您的输出消息不符。

答案 1 :(得分:1)

没有任何数学分析:

  ...

  do 
  {   
    c = 0;
    t += b;
    b++;

    for (d = 1; d < t; ++d)
    {       
      if (!(t % d))
      {
        c++;
      }       
    }
  } while (c <= 500);

  ...

答案 2 :(得分:1)

您正在实施O(n ^ 2)算法。如果代码花了不到半个小时就会令人惊讶。

与以下强力方法相比,请参阅您的计算机科学教科书:检查1,1 + 2,1 + 2 + 3等。

您可以缩短内部for循环。对于划分三角数的因子,是否真的需要一直检查t。例如,10可以被任何大于5的数字整除吗?或任何大于50的数字100?

因此,给定数N,可以均分N的最大数是多少? 继续阅读/研究这个问题。

另外,正如其他人提到的那样,外部循环可以简单地编码为:

  while (1)
  {
    // etc.
  }

那么,是否需要声明ea?请注意,这不会影响时间长度,但您的编码风格表明您仍在学习,因此审稿人会质疑您的代码所做的一切!!

答案 3 :(得分:0)

你正在做一些不必要的操作,如果我们能够简单地检查一下,我认为根本不需要这些说明。

首先:

while(e!=0)

当您声明e=1时,如果只将1置于循环中,它将起作用。您没有在任何地方更新e的值。

更改并检查其是否正常工作。

答案 4 :(得分:0)

关于三角形数字的一个美妙的事情是,如果你有一个三角形数字,只需要一个简单的加法操作,就可以得到下一个数字。