使用 GCD 查找从 1 到 N 的所有素数(埃拉托色尼筛的另一种方法)

发布于 2025-01-13 06:59:39 字数 710 浏览 0 评论 0原文

要找到从 1 到 N 的所有素数。

我知道我们通常使用埃拉托斯特尼筛法来解决这个问题,我想到了另一种使用 gcd 的方法,希望得到您的意见。

我的做法->

如果所有素数都被处理直到任何迭代,则保留一个维护变量。如果该变量的 gcd,则数字 i ==1。这意味着没有。是互质的,所以我一定是质数。

例如:gcd(210,11) == 1,所以 11 是质数。 {210=2*3*5*7}

伪代码:

Init num_list={contains numbers 2 to N} [since 0 and 1 arent prime nos.]
curr_gcd = 2, gcd_val=1
For i=3;i<=N;i++
    gcd_val=__gcd(curr_gcd,i)
    if gcd_val == 1 //(prime)
          curr_gcd = curr_gcd * i
    else //(composite so remove from list)
         numList.remove(i)

或者,我们也可以有一个列表并将素数推入该列表。 SC = O(N) TC = O(N log(N)) [TC 使用欧几里德方法计算 gcd => O(log(max(a,b)))]

这看起来正确还是我在这里错误地计算了 TC。请发表您对此的看法。 蒂亚!

To find all prime numbers from 1 to N.

I know we usually approach this problem using Sieve of Eratosthenes, I had an alternate approach in mind using gcd that I wanted your views on.

My approach->

Keep a maintaining a variable if all prime numbers are processed till any iteration. If gcd of this var, number i ==1. That means the nos. are co-prime so i must be prime.

For ex: gcd(210,11) == 1, so 11 is prime.
{210=2*3*5*7}

Pseudocode:

Init num_list={contains numbers 2 to N} [since 0 and 1 arent prime nos.]
curr_gcd = 2, gcd_val=1
For i=3;i<=N;i++
    gcd_val=__gcd(curr_gcd,i)
    if gcd_val == 1 //(prime)
          curr_gcd = curr_gcd * i
    else //(composite so remove from list)
         numList.remove(i)

Alternatively, we can also have a list and push the prime numbers into that list.
SC = O(N)
TC = O(N log(N)) [TC to calculate gcd using euclid's method => O(log(max(a,b)))]

Does this seem right or I am calculating the TC incorrectly here. Please post your views on this.
TIA!

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

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

发布评论

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

评论(2

云雾 2025-01-20 06:59:39

正如许多评论中指出的那样,看起来我的方法的时间复杂度更接近 O(log^2(n)) 。

此外,随着 N 的增加,curr_gcd 变量会变得非常大,并且肯定会溢出 int 和 long 大小限制。

感谢所有回复的人!

Looks like the time complexity of my approach is closer to O(log^2(n)) as pointed out by many in the comments.

Also, the curr_gcd var would become quite large as N is increased and would definitely overflow int and long size limits.

Thanks to everyone who responded!

跨年 2025-01-20 06:59:39

也许你的方法理论上是正确的,但显然,它并不出色。

它的效率比SoE差,它需要的数据范围太大。因此,也许它看起来很优雅,但使用起来却很困难。

在我看来,“找到从 1 到 N 的所有素数”已经是一个众所周知的问题,这意味着它的解决方案是经过深思熟虑的。

一开始,也许我们会用暴力来处理这样的事情。

int primes[N],cnt;//store all prime numbers
bool st[N];//st[i]:whether i is rejected
void get_primes(int n){
    for(int i=2;i<=n;i++){
        if(st[i]) continue;
        primes[cnt++]=i;
        for(int j=i+i;j<=n;j+=i){
            st[j]=true;
        }
    }
}

这是一个O(n^2)时间算法。太慢了,难以忍受。

前进。我们有 SoE,它使用 O(nlognlogn) 时间。

但我们有一个更好的算法,称为“线性筛”,它只使用O(n)时间,正如它的名字一样。我用C语言是这样实现的。

int primes[N],cnt;
bool st[N];
void get_primes(int n){
    for(int i=2;i<=n;i++){
        if(!st[i]) primes[cnt++]=i;
        for(int j=0;primes[j]*i<=n;j++){
            st[primes[j]*i]=true;
            if(i%primes[j]==0) break;
        }
    }    
}

这个O(n)算法是我用来解决各大IT公司和各种OJ中出现的这类算法问题的。

Maybe your method is theoretically right,but evidently, it's not excellent.

It's efficiency is worse than SoE, the range of data that it needs is too large. So maybe it seems elegant to look but hard to use.

In my views, "To find all prime numbers from 1 to N" is already a well-known problem and that means it's solution is well considered.

At first, maybe we use brute-force to deal with it like this.

int primes[N],cnt;//store all prime numbers
bool st[N];//st[i]:whether i is rejected
void get_primes(int n){
    for(int i=2;i<=n;i++){
        if(st[i]) continue;
        primes[cnt++]=i;
        for(int j=i+i;j<=n;j+=i){
            st[j]=true;
        }
    }
}

it's a O(n^2) time algorithm.Too slow to endure.

Go ahead. We have SoE, which use O(nlognlogn) time.

But we have a better algorithm called "liner sieve", which only use O(n) time, just as it's name. I implement it with C language like this.

int primes[N],cnt;
bool st[N];
void get_primes(int n){
    for(int i=2;i<=n;i++){
        if(!st[i]) primes[cnt++]=i;
        for(int j=0;primes[j]*i<=n;j++){
            st[primes[j]*i]=true;
            if(i%primes[j]==0) break;
        }
    }    
}

this O(n) algorithm is used by me to slove this kind of algorithm problems that appear in major IT companies and many kinds of OJ.

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