程序的时间复杂度

发布于 2024-08-03 04:02:02 字数 1830 浏览 5 评论 0原文

 #include<stdio.h>
 #include<time.h>

 int main()

  {

    clock_t start;
    double d;
    long int n,i,j;
    scanf("%ld",&n);
    n=100000;
    j=2;
    start=clock();
    printf("\n%ld",j);

       for(j=3;j<=n;j+=2)
       {
          for(i=3;i*i<=j;i+=2)

          if(j%i==0)
            break;

           if(i*i>j)
          printf("\n%ld",j);

        }
    d=(clock()-start)/(double)CLOCKS_PER_SEC;
    printf("\n%f",d);

}

当 n=100000 时,上述程序的运行时间为 0.015 秒。 我还在 C 中实现了埃拉托色尼筛法算法,并在 n=100000 时得到了 0.046 的运行时间。

我的上述算法比我实现的 Sieve 算法更快吗?

我上面的程序的时间复杂度是多少?

我的筛子的实现

 #define LISTSIZE 100000    //Number of integers to sieve<br>
 #include <stdio.h>
 #include <math.h>
 #include <time.h>

int main()
{   


    clock_t start;
    double d;
    long int list[LISTSIZE],i,j;
    int listMax = (int)sqrt(LISTSIZE), primeEstimate = (int)(LISTSIZE/log(LISTSIZE));

    for(int i=0; i < LISTSIZE; i++)
        list[i] = i+2;
    start=clock();

    for(i=0; i < listMax; i++)
    {
        //If the entry has been set to 0 ('removed'), skip it
        if(list[i] > 0)
        {
            //Remove all multiples of this prime
            //Starting from the next entry in the list
            //And going up in steps of size i
            for(j = i+1; j < LISTSIZE; j++)
            {
                if((list[j] % list[i]) == 0)
                    list[j] = 0;
            }
        }
    }
    d=(clock()-start)/(double)CLOCKS_PER_SEC;

    //Output the primes
    int primesFound = 0;
    for(int i=0; i < LISTSIZE; i++)
    {
        if(list[i] > 0)
        {
            primesFound++;

            printf("%ld\n", list[i]);
        }
    }
    printf("\n%f",d);
    return 0;
}
 #include<stdio.h>
 #include<time.h>

 int main()

  {

    clock_t start;
    double d;
    long int n,i,j;
    scanf("%ld",&n);
    n=100000;
    j=2;
    start=clock();
    printf("\n%ld",j);

       for(j=3;j<=n;j+=2)
       {
          for(i=3;i*i<=j;i+=2)

          if(j%i==0)
            break;

           if(i*i>j)
          printf("\n%ld",j);

        }
    d=(clock()-start)/(double)CLOCKS_PER_SEC;
    printf("\n%f",d);

}

I got the running time of 0.015 sec when n=100000 for the above program.
I also implemented the Sieve of Eratosthenes algorithm in C and got the running time of 0.046 for n=100000.

How is my above algorithm faster than Sieve's algorithm that I have implemented.

What is the time complexity of my above program??

My sieve's implementation

 #define LISTSIZE 100000    //Number of integers to sieve<br>
 #include <stdio.h>
 #include <math.h>
 #include <time.h>

int main()
{   


    clock_t start;
    double d;
    long int list[LISTSIZE],i,j;
    int listMax = (int)sqrt(LISTSIZE), primeEstimate = (int)(LISTSIZE/log(LISTSIZE));

    for(int i=0; i < LISTSIZE; i++)
        list[i] = i+2;
    start=clock();

    for(i=0; i < listMax; i++)
    {
        //If the entry has been set to 0 ('removed'), skip it
        if(list[i] > 0)
        {
            //Remove all multiples of this prime
            //Starting from the next entry in the list
            //And going up in steps of size i
            for(j = i+1; j < LISTSIZE; j++)
            {
                if((list[j] % list[i]) == 0)
                    list[j] = 0;
            }
        }
    }
    d=(clock()-start)/(double)CLOCKS_PER_SEC;

    //Output the primes
    int primesFound = 0;
    for(int i=0; i < LISTSIZE; i++)
    {
        if(list[i] > 0)
        {
            primesFound++;

            printf("%ld\n", list[i]);
        }
    }
    printf("\n%f",d);
    return 0;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

浅忆 2024-08-10 04:02:02

有很多因素可能会影响您的结果。可以肯定的是,我们需要查看您的筛子实现的代码。另外,您计算机上时钟功能的分辨率是多少?如果实施不允许达到毫秒级的高精度,那么您的结果可能会在测量误差范围内。

我怀疑问题出在这里:

            //Remove all multiples of this prime
            //Starting from the next entry in the list
            //And going up in steps of size i
            for(j = i+1; j < LISTSIZE; j++)
            {
                    if((list[j] % list[i]) == 0)
                            list[j] = 0;
            }

这是删除所有素数倍数的糟糕方法。为什么不使用内置的乘法运算符来删除倍数呢?这个版本应该快得多:

            //Remove all multiples of this prime
            //Starting from the next entry in the list
            //And going up in steps of size i
            for(j = list[i]; j < LISTSIZE; j+=list[i])
            {
              list[j] = 0;
            }

There are a number of things that might influence your result. To be sure, we would need to see the code for your sieve implementation. Also, what is the resolution of the clock function on your computer? If the implementation does not allow for a high degree of accuracy at the millisecond level, then your results could be within the margin of error for your measurement.

I suspect the problem lies here:

            //Remove all multiples of this prime
            //Starting from the next entry in the list
            //And going up in steps of size i
            for(j = i+1; j < LISTSIZE; j++)
            {
                    if((list[j] % list[i]) == 0)
                            list[j] = 0;
            }

This is a poor way to remove all of the multiples of the prime number. Why not use the built in multiplication operator to remove the multiples? This version should be much faster:

            //Remove all multiples of this prime
            //Starting from the next entry in the list
            //And going up in steps of size i
            for(j = list[i]; j < LISTSIZE; j+=list[i])
            {
              list[j] = 0;
            }
夜雨飘雪 2024-08-10 04:02:02

我上面的程序的时间复杂度是多少?

为了凭经验测量程序的时间复杂度,您需要多个数据点。针对多个 N 值运行程序,然后绘制 N 与时间的关系图。您可以使用电子表格、GNUplot 或方格纸和铅笔来完成此操作。您还可以使用软件和/或简单的旧数学来找到适合您的数据的多项式曲线。

非经验性:关于分析计算复杂性,已经写了很多文章(并在计算机科学课程中讲授)。关于计算复杂性理论的维基百科文章可能会为进一步阅读提供一些起点。

What is the time complexity of my above program??

To empirically measure the time complexity of your program, you need more than one data point. Run your program for multiple values of N, then make a graph of N vs. time. You can do this using a spreadsheet, GNUplot, or graph paper and pencil. You can also use software and/or plain old mathematics to find a polynomial curve that fits your data.

Non-empirically: much has been written (and lectured in computer science classes) about analyzing computational complexity. The Wikipedia article on computational complexity theory might provide some starting points for further reading.

琉璃繁缕 2024-08-10 04:02:02

您的筛子实施不正确;这就是为什么它这么慢的原因:

  • 你不应该把它变成一个数字数组,而是一个标志数组(你仍然可以使用 int 作为数据类型,但 char 也可以)
  • 你不应该使用索引数组的移位,但 list[i] 应该确定 i 是否是素数(而不是 i+2 是否是素数),
  • 您应该通过这些修改从 i=2 开始消除
  • ,您应该遵循 1800 INFORMATION 的建议,并使用以 i 步长而不是 1 步长的循环取消 i 的所有倍数

Your sieve implementation is incorrect; that's the reason why it is so slow:

  • you shouldn't make it an array of numbers, but an array of flags (you may still use int as the data type, but char would do as well)
  • you shouldn't be using index shifts for the array, but list[i] should determine whether i is a prime or not (and not whether i+2 is a prime)
  • you should start the elimination with i=2
  • with these modifications, you should follow 1800 INFORMATION's advice, and cancel all multiples of i with a loop that goes in steps of i, not steps of 1
烟织青萝梦 2024-08-10 04:02:02

只是为了您的时间复杂度:

您有一个 ~LISTMAX 迭代的外循环和一个 max 的内循环。 LISTSIZE 迭代。这意味着你的复杂性是

O(sqrt(n)*n)

其中 n = 列表大小。它实际上要低一些,因为内部循环每次都会减少计数,并且仅针对每个未知数运行。但这很难计算。由于 O 表示法提供了上限,因此 O(sqrt(n)*n) 应该没问题。

Just for your time complexity:

You have an outer loop of ~LISTMAX iterations and an inner loop of max. LISTSIZE iterations. This means your complexity is

O(sqrt(n)*n)

where n = listsize. It is actually a bit lower since the inner loop reduces it's count eacht time and is only run for each unknown number. But that's difficult to calculate. Since the O-Notation offers an upper bound, O(sqrt(n)*n) should be ok.

以可爱出名 2024-08-10 04:02:02

这种行为很难预测,但您应该考虑到访问内存并不便宜......对于小素数再次计算它可能会更快。

The behaviour is difficult to predict, but you should take into account that accessing the memory is not cheap... it's probably faster to just calculate it again for small primes.

蓝戈者 2024-08-10 04:02:02

这些运行时间太短,没有意义。系统时钟分辨率不准确到这种水平。

为了获得准确的计时信息,您应该做的是循环运行您的算法。重复数千次以使运行时间至少达到一秒,然后您可以将时间除以循环次数。

Those run times are too small to be meaningful. The system clock resolution is not accurate to that kind of level.

What you should do to get accurate timing information is run your algorithm in a loop. Repeat it a few thousand times to get the run time up to at least a second, then you can divide the time by the number of loops.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文