2016-07-08 84 views
-1

我正在通過本書的方式學習C++編程原理和實踐。在書中有一個練習,通過檢查一個數字來查找質數,這個數字已經被確定爲素數。這是我寫的解決這個問題的功能。使用C++函數進行練習來識別素數使用!=

vector <int> primes; 

int findprime (int x) { 
    for (int p=0; p<primes.size(); ++p) { 
     if (x%primes[p]!=0) { 
      return x; 
     } 
    } 
} 

int main() { 
    primes.push_back(2); 
    for (int i=3; i<100; ++i) { 
     primes.push_back(findprime(i)); 
    } 
    for (int i=0; i<primes.size(); ++i) { 
     cout << primes[i] << '\n'; 
    } 
} 

在他的解決辦法作者的功能是:

bool is_prime(int n) { 
    for (int p = 0; p<prime.size(); ++p) 
     if (n%prime[p]==0) return false; // no remainder: prime[p] divided 

    return true; // no smaller prime could divide 
} 

我的代碼不工作,但我真的不明白爲什麼。我想我錯過了一些關於這些功能如何運作的知識。如果有人會解釋我的代碼不起作用並填寫我的空白,我會非常感激。

+0

你得到任何錯誤或結果是錯誤的? – denis

+0

我的結果是錯誤的。將1-100之間的每個數字放入向量中。我認爲即使通過我已經指定的函數只會返回值,如果其!!它不管返回值。我相信我對函數的運作有些誤解,希望有經驗的人能解釋一下。 – TrustNo1UK

回答

2

您正在通過到達定義的函數的末尾來調用未定義的行爲,以返回值而不返回任何內容。你的編譯器應該發出警告。如果沒有,那麼你應該打開編譯器警告。

findprime總是返回一些int,但如果x是不是由primes的值之一整除,那麼你將到達函數的結尾而沒有遇到return聲明。在這種情況下應該返回什麼?答案是答案沒有說明。在這種情況下,實現可以自由地做任何事情。在這種情況下,它似乎只是返回x

+0

你知道哪些選項需要在代碼塊中啓用以獲得相關的編譯器警告? – TrustNo1UK

+0

我不知道在代碼塊中設置編譯器標誌的位置,但我認爲它使用g ++作爲它的編譯器。如果是這種情況,您希望在這種情況下使用'-Wreturn-type'標誌。我會推薦'-Wall',它會打開大多數警告,包括'-Wreturn-type'警告。 –

1

這裏的清理代碼,與錯誤和修復註釋[請原諒無償風格清理]:

#include <vector> 
#include <iostream> 
std::vector <int> primes; 

// NOTE/BUG: before this was returning the inverse sense 
// RETURNS: 0=not prime, 1=prime 
int 
findprime(int x) 
{ 
    for (int p = 0; p < primes.size(); ++p) { 
     if (x % primes[p] == 0) { 
      return 0; 
     } 
    } 

    // BUG: this return was missing 
    return 1; 
} 

int 
main() 
{ 
    primes.push_back(2); 

    for (int i = 3; i < 100; ++i) { 
     // BUG: before this was _always_ adding the number 
#if 0 
     primes.push_back(findprime(i)); 
#else 
     if (findprime(i)) 
      primes.push_back(i); 
#endif 
    } 

    for (int i = 0; i < primes.size(); ++i) { 
     std::cout << primes[i] << '\n'; 
    } 
} 
0

你和作者的解決方案是不同的:

作者的邏輯是檢查某些數字的素數n。如果任何素數均勻分配n,並且僅在檢查結束true的所有素數之後,它通過提早退出來做到這一點。

你的代碼int findprime (int x)不是這個。它返回x,如果x不能平分至少一個現有的素數。因爲它明確地將每個數字都加上了素數,所以它總能找到一些不能完美分割的數字。正如其他人提到的那樣,函數寫得不好,因爲它可以以避免所有return語句的方式進行分支(不好,導致未定義的行爲)。

我建議使用作者的版本,並研究它爲什麼有效 - 它的工作原理是因爲當它確實退出時,它確實如此。不能被一個素數劃分本身並不能保證你處理一個素數,而是當所有素數不會將你的數字分開 - 如果任何都可以分開,那麼數字不是素數,也不需要進一步檢查。有更先進的測試,但是素性測試和尋找素數是它自己的主題,用於研究超越任何編程語言或方法的具體內容。

0

此代碼應該工作:

int findprime(int x) 
{ 
    for (int p=0; p<primes.size(); p++) 
    { 
     if ((x%primes[p])==0) 
     { 
      return -1; 
      break; 
     } 
    } 
return x; 
} 

int main() 
{ 
    primes.push_back(2); 
    primes.push_back(3); 
    for (int i=3; i<100; ++i) 
    { 
     if(findprime(i)!=-1) 
     { 
     primes.push_back(i); 
     } 
    } 
    for (int i=0; i<primes.size(); ++i) 
    { 
     cout << primes[i] << '\n'; 
    } 
} 

如在它被上述的回答中的一個。你正在經歷矢量的所有價值,並且最終不會返回任何東西。