簡體   English   中英

更好的算法來檢查一個數字是否既不是素數也不是單個素數的冪

[英]Better algorithm to check if a number is neither a prime nor a power of a single prime

我有以下程序,其中t可以取值從 1 到 100000,而n可以取值 1 到 10^9。

#define MAX 10000000

using namespace std;

unordered_set<long long int> s;

bool morethanone(long long int n)
{
    long long int check=0;
    for(unordered_set<long long int>::iterator it=s.begin();it!=s.end();it++)
    {
        if(n%(*it)==0)
            check++;
        if(check>1)
            return false;
    }
    return true;
}

bool isprime(long long int n)
{
    if(n%2==0)
        return false;
    for(long long int i=3;i<=sqrt(n);i+=2)
        if(n%i==0)
            return false;
    return true;
}

int main() 
{
s.insert(2);
s.insert(3);
for(long long int i=4;i<=MAX;i++)
{
        if(isprime(i))
            s.insert(i);
}

long long int t,n;
scanf("%lld",&t);
for(long long int test=0;test<t;test++)
{
    scanf("%lld",&n);
    if(n==1||s.find(n)!=s.end())
        cout<<"Santa\n";
    else if(morethanone(n))
        cout<<"Santa\n";
    else
        cout<<"Banta\n";
}

return 0;
}

基本上,程序生成素數直到 10^9,如果給定的數字是素數或單個素數或 1 的冪,則打印“聖誕老人”。

上述程序適用於 MAX=10^6,但對於超出該值的任何值均顯示“因超時而終止”。

您想確定是否可以將n寫為p k ,其中p 個素數和k > 0 積分。

Henri Cohen 在其著作A Course in Computational Algebraic Number Theory 的算法 1.7.5 中描述了一個答案。 他利用了費馬小定理和米勒-拉賓素性測試器發現的n復合性的見證。 科恩證明了如果a是一個見證n的compositeness,在米勒羅賓測試的意義上,則gcd上述(-,n)n的非平凡除數(即,它是在1和n )。

我將這個想法簡化為 Python 代碼 http://ideone.com/cNzQYr並在 我的博客上給出更全面的解釋。 這是來自 ideone.com 的有趣代碼,因為 Stack Overflow 不會讓我在沒有它的情況下發帖; 去那里看看剩下的:

# returns p,k such that n=p**k, or 0,0
# assumes n is an integer greater than 1
def primePower(n):
    def checkP(n, p):
        k = 0
        while n > 1 and n % p == 0:
            n, k = n / p, k + 1
        if n == 1: return p, k
        else: return 0, 0
    if n % 2 == 0: return checkP(n, 2)
    q = n
    while True:
        a = findWitness(q)
        if a == 0: return checkP(n, q)
        d = gcd(pow(a,q,n)-a, q)
        if d == 1 or d == q: return 0, 0
        q = d

有許多高級方法可以快速計算素數,但改進代碼的一個簡單方法是僅檢查下一個候選數是否可以被您目前找到的一個素數整除。 當您將質數保留在允許排序的數據結構中時,您可以在達到大於候選數平方根的質數時停止。

正如評論中提到的,分塊篩選也是可能的,可以結合上述改進。 現在你只檢查奇數,這實際上是用塊大小 2 進行篩選。如果你檢查候選者不能被 3 整除,你可以檢查塊大小 6。這意味着省略塊中的每個偶數位置和位置有一個(基於一的)索引可以被 3 整除,所以只有索引 1 和 5。等等......

檢查一個數是否是單個素數的冪也可以改進。 一旦你找到一個可以被它整除的素數,檢查它是否是這個素數的冪(寫另一種方法)並立即停止。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM