2012-08-01 24 views
1

我在使用此C++代碼時遇到問題。整數num是我想檢查它是否爲素數的一個數字。但是這個程序總是返回false。這可能很簡單,但我找不到任何東西。用於檢查素數不工作的C++代碼

for(int i=2;i<num;i++){ //primes are allowed to be divided by 1 so we start at 2 
     if(num % i == 0){ //can be divided by a number other than itself or 1 so we trip out 
      return false; 
     } else if(i == num){ //if we've already done checks as high as possible and not tripped out yet then report success 
      return true; 
     } 
} 

回答

7

i == num不會發生,因爲你的循環條件是i<num。嘗試:

for(int i=2;i<num;i++){ //primes are allowed to be divided by 1 so we start at 2 
    if(num % i == 0){ //can be divided by a number other than itself or 1 so we trip out 
     return false; 
    } else if(i == num-1){ //if we've already done checks as high as possible and not tripped out yet then report success 
     return true; 
    } 
} 

正如下面指出的,這裏的else條件是多餘的,你只需要檢查2至sqrt(num) - 因爲其餘的因素已經得到遏制。

根據您想要解決問題的複雜程度,可以進行更多改進。現實中的大多數方法都使用概率算法。

+0

謝謝,這是有效的。將接受10分鐘(當它讓我) – stackunderflow 2012-08-01 06:44:14

+2

for(i == 2; i 2012-08-01 06:48:52

+0

沒有必要迭代到'num'。迭代到'num/2'就足夠了。 – cppcoder 2012-08-01 06:52:44

4

您不必檢查每個數字,因爲很多數字都可以輕易排除。例如,在檢查num不能被2整除後,您可以跳過所有其他偶數。這爲您節省了一半的測試。

我們也肯定知道任何其他因素必須小於num/2(或者真的是sqrt(num),但這很難計算)。這些知識可以爲我們節省另外一半的測試。

所以現在我們有:

if (num % 2 == 0) 
    return false; 

for(int i = 3; i < num/2; i += 2){ 
    if(num % i == 0){ //can be divided by a number other than itself or 1 so we trip out 
     return false; 
    } 
} 

// arriving here we have found no factors, so it must be a prime 
return true; 
+1

「*(或者真的是'sqrt(num)',但是這很難計算)*」但是你有代碼非常的句子。 ; - ] – ildjarn 2012-08-01 07:54:48

+0

既然你已經提到過,計算sqrt真的超過從srqt - > num/2?由於計算sqrt價格昂貴,我們不會因爲在sqrt停止而獲得任何優勢嗎? – Mohan 2012-08-01 07:54:53

+0

我只是在這裏挑選一些低懸的水果,削減75%的運行時間。我們做的任何其他事情顯然都會影響剩下的25% - 是否值得額外付出努力?這取決於。 – 2012-08-01 08:01:07

1
bool CheckPrime(int num) { 
    bool yayornay = true; 
    for(int i = 2; i < num; i++) { 
     if(num % i == 0) { 
      yayornay = false; 
      break; 
     } 
    } 
    return yayornay; 
} 
+0

沒有'break'?效率過低。 – ildjarn 2012-08-01 07:58:11

+0

正如我們所說的編輯 – 2012-08-01 08:01:45

+1

@JeffSchweigler您錯過了if的括號。沒有大括號,你的代碼將在第一次迭代中破解。編輯糾正相同。 – Mohan 2012-08-01 08:57:34

0

這裏寫的正確方法你的意思:

int i=2;      // move declaration out 
for(/*int i=2*/;i<num;i++){ 
     if(num % i == 0){ 
      return false; 
     } // else   // and the final test too 
} 
if(i == num){     
    return true; 
} 

但是,這不是有效的。你只需要檢查i的不超過sqrt(num)。另外,如果你檢查num%2,有沒有更多需要檢查其他任何偶數,所以你可以使用的2增量或者你甚至可以通過數:

if(num == 2 || num == 3) return true; 
if(num < 2 || num % 2 == 0 || num % 3 == 0) return false; 
for(int i=5, j=7, lim=sqrt(num); i<=lim; i+=6, j+=6){ 
     if(num % i == 0 || num % j == 0){ 
      return false; 
     } 
} 
return true; 

(注意:這是比這裏的另一個答案更有效,它說這是對這個答案的初始版本的「優化」)。

1

Will Ness的代碼的一個小的優化,只需計算for的外部sqrt數。條件檢查執行很多次,並且沒有意義每次計算sqrt。

if(num == 2) return true; 
if(num < 2 || num % 2 == 0) return false; 
int sqrt = sqrt(num); 

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

到目前爲止,我認爲這是最有效的方法!

+0

我假定編譯器會執行該優化。 :)順便說一句我已經編寫了代碼,應該使它快大約30%,我認爲。 – 2012-08-01 12:45:30

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

您的解決方案與@ZelterAdy非常相似。但是,他的算法比你的算法更有效率。那麼你有什麼理由發佈另一個不提供任何附加價值的解決方案? – honk 2014-10-25 14:11:45