日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

寻找素数算法

發(fā)布時(shí)間:2025/3/21 编程问答 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 寻找素数算法 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

找素?cái)?shù)

暴力求解

  • 時(shí)間復(fù)雜度: O(n*sqrt(n))

原理

暴力求解是對(duì)[m,n]的每一個(gè)整數(shù)都判斷是否為素?cái)?shù),由數(shù)學(xué)可知,一個(gè)數(shù)i的因數(shù)關(guān)于sqrt(i)對(duì)稱分布,故我們只需判斷[2,sqrt(i)]的整數(shù)中有沒有i的因數(shù)即可

代碼

vector<int> fuckingFindPrime(int m,int n) {vector<int> prime;if(m<=n){for(int i=m; i<=n; i++){bool flag = true;for(int j=2; j<=sqrt(i); j++) //需要調(diào)用math.h頭文件{if(!(i%j)){flag = false;break;}}if(!flag) continue;else prime.push_back(i);}} return prime; }

埃氏篩法

  • 時(shí)間復(fù)雜度: O(n*log(n))

原理

首先,2是最小質(zhì)數(shù),所以先把2在n以內(nèi)的所有倍數(shù)篩選掉。然后,3也是質(zhì)數(shù),故把3的所有倍數(shù)篩選掉。4不是質(zhì)數(shù),且4為2的倍數(shù),已經(jīng)被篩選掉,跳過。5是質(zhì)數(shù)。。。。然后依次類推,最后剩下的就都是質(zhì)數(shù)了。

代碼

vector<int> EratosthenesSieve(int n) {vector<int> num;vector<int> prime;for(int i=0; i<=n; i++)num.push_back(i);//把[0,n]的整數(shù)初始化num[1] = 0; //1公認(rèn)不是素?cái)?shù),把1去掉for(int i=2; i<=n; i++){if(!num[i])continue;//被置為0的數(shù)不是素?cái)?shù),所以跳過本輪循環(huán)去判斷下一個(gè)位置prime.push_back(i); //是素?cái)?shù),保存到prime中//以下為埃氏篩的關(guān)鍵,參考上文的“原理”部分for(int j=i; i*j<=n&&j<n; j++)num[i*j] = 0;}return prime; }

提示

如果要尋找區(qū)間[m,n]的素?cái)?shù),只需用埃氏篩打表n以內(nèi)的素?cái)?shù)向量prime(或數(shù)組),然后在prime中找到不小于m的最小素?cái)?shù),一直輸出到不大于n為止

比如,尋找[50,90]的素?cái)?shù),代碼可以如下

int main() {vector<int> prime = EratosthenesSieve(90);int i=0;while(prime[i]<50) i++;for(int j=i; prime[j]<=90; j++)cout << prime[j] << " ";cout << endl;return 0; }

當(dāng)然,這只是個(gè)簡(jiǎn)單的例子,你也可以用更高效的查找算法于prime中尋找,因?yàn)楸疚闹黝}為尋找素?cái)?shù),所以查找方面不過多敘述

歐拉篩(線性篩)

  • 時(shí)間復(fù)雜度: O(n)

原理

其將合數(shù)分為 合數(shù) = 最小質(zhì)因數(shù)*合數(shù) 的形式,通過最小質(zhì)因數(shù)判斷是否被標(biāo)記。故相對(duì)于埃氏篩,歐拉篩不會(huì)反復(fù)標(biāo)記一個(gè)合數(shù),效率更高。

代碼

vector<int> EulerSieve(int n) {int pNum = 0; //記錄素?cái)?shù)的個(gè)數(shù)vector<int> prime;vector<bool> isPrime; //用于標(biāo)記//對(duì)標(biāo)記向量初始化for(int i=0; i<n; i++)isPrime.push_back(false);for(int i=2; i<=n; i++){if(!isPrime[i]) //沒有被篩選過,則為素?cái)?shù){pNum++;prime.push_back(i);}for(int j=0; j<pNum && i*prime[j]<=n; j++){isPrime[i*prime[j]] = true; //將已經(jīng)記錄的素?cái)?shù)倍數(shù)標(biāo)記//下方為歐拉篩的核心if(!(i%prime[j])) break;}}return prime; }

核心

歐拉篩妙就妙在它的核心處

? 若

? i是prime[j]的整數(shù)倍k

? 則

? i · prime[j+1] = k · prime[j] · prime[j+1] = k · prime[j+1] · prime[j]

? i · prime[j+1]為 prime[j] 的整數(shù)倍,不需要被標(biāo)記,prime[j+2]…prime[j+…] 同理

? 故

? 該推導(dǎo)告訴我們不需要去標(biāo)記后面的數(shù),直接跳出循環(huán)即可

提示

歐拉篩法同埃氏篩一樣為打表方法,想要獲取[m,n]的素?cái)?shù)要去查表

《新程序員》:云原生和全面數(shù)字化實(shí)踐50位技術(shù)專家共同創(chuàng)作,文字、視頻、音頻交互閱讀

總結(jié)

以上是生活随笔為你收集整理的寻找素数算法的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。