<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
素數又稱質數。一個大於1的自然數,除了1和它自身外,不能被其他自然數整除的數叫做素數;否則稱為合數(規定1既不是素數也不是合數)。
在許多的程式設計題目中,都會涉及到素數的判斷,那我們該如何有效判斷素數呢?
根據素數的定義,我們可以使用逐個試除的方式來判斷素數,如果能為要判斷的數找到一個除了1和自身以外的因數,那麼它就是合數;反之,就是素數。
而這樣的因數的範圍必然在 2 ~ √n之間,所以我們便可以得到以下程式碼。
int isPrime(int n) { if(n <= 1) { return 0; } for (int i = 2; i * i <= n; i++) { if (n % i == 0) { return 0; } } return 1; }
該函數就可以判斷輸入的數是否為素數。
這個範圍還可以更進一步地縮小。
數學上有一個定理,除了2和3外,只有形如6n-1和6n+1的自然數可能是素數,這裡的n是大於等於1的整數。
如何理解這個定理呢?
所有自然數都可以寫成6n,6n+1,6n+2,6n+3,6n+4,6n+5這6種。 那麼我們就可以得到下表。
自然數 | 是否可能是素數 |
---|---|
6n | 不可能,為2的倍數 |
6n+1 | 可能 |
6n+2 | 不可能,為2的倍數 |
6n+3 | 不可能,為3的倍數 |
6n+4 | 不可能,為2的倍數 |
6n+5 | 可能 |
其中6n+5可以寫作6n-1,所以除了2和3的素數必然形如6n-1或6n+1。
於是我們可以寫出如下程式碼。
int isPrime(int n) { if(n <= 1) return 0; else if(n == 2 || n == 3) return 1; else if(n % 6 != 1 && n % 6 != 5) return 0; for (int i = 5; i * i <= n; i++) { if (n % i == 0) { return 0; } } return 1; }
優化後的演演算法具有更高的效率。
暴力演演算法雖然可以判斷某個數是否為素數,但是當它面對大量需要判斷的資料時,它的效率會顯得十分低下,我們也有更好地方法來求一定範圍裡的素數,它就是我們的篩法。
篩法,顧名思義,就是將合數從資料中篩除,剩下的自然就都是素數了。
篩法也分為兩種,讓我們來逐一介紹。
埃拉託斯特尼 篩法,簡稱 埃氏篩,是一種由希臘數學家埃拉託斯特尼所提出的一種簡單檢定素數的演演算法。
要得到自然數n以內的全部素數,必須把不大於根號n的所有素數的倍數剔除,剩下的就是素數。
下面的程式就是通過埃氏篩判斷 0 ~ MAXSIZE-1是否為素數。
#define MAXSIZE 10000 int isPrime[MAXSIZE] = { 0 }; void sieveOfEratosthenes() { for (int i = 2; i < MAXSIZE; i++) { isPrime[i] = 1; } for (int i = 2; i * i < MAXSIZE; i++) { if (isPrime[i]) { for (int j = i * 2; j < MAXSIZE; j += i) { isPrime[j] = 0; } } } }
埃氏篩的時間複雜度是O(n*loglogn),效率相較於原來的暴力演演算法已經有了很大的提高,但它仍然有具有一定的不足。
對於多個素數的公倍數,可能會被多次篩去。
為了解決這個問題,數學家尤拉優化了演演算法,於是就有了新的篩法。
尤拉篩法,簡稱尤拉篩或是歐式篩,又因為其O(n)的時間複雜度而被稱為線性篩。
尤拉篩將合數分解為(最小質因數 * 一個合數)的形式,通過最小質因數來判斷當前合數是否已經被標記過,與埃氏篩相比,不會對已經被標記過的合數再進行重複標記,故效率更高。
下面的程式就是通過尤拉篩判斷 0 ~ MAXSIZE-1是否為素數。
#define MAXSIZE 10000 int isPrime[MAXSIZE] = { 0 }; int prime[MAXSIZE]; int cnt = 0; void sieveOfEuler() { for (int i = 2; i < MAXSIZE; i++) { prime[i] = 1; } for (int i = 2; i * i < MAXSIZE; i++) { if (isPrime[i]) { prime[++cnt] = i; } for (int j = 1; i * prime[j] < MAXSIZE; j++) { isPrime[i * prime[j]] = 0; //若i為prime[j]的倍數,終止迴圈,避免重複篩除 if (i % prime[j] == 0) break; } } }
在求一定範圍中的所有素數時,尤拉篩具有無可比擬的優勢,在程式設計中也經常被採用。
到此這篇關於C++兩種素數判定方法的文章就介紹到這了,更多相關C++素數判定內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45