簡體   English   中英

素數查找算法返回奇怪的值

[英]Prime Number finding algorithm returns weird values

我開始學習 c++,並且正在通過 Project Euler 挑戰,#7 要求您找到給定范圍內的所有素數。 經過在線研究,我決定嘗試使用Sieve of Erastothenes ,但是使用我設置的代碼,當我要求 2 個素數和 (2, 4, 5, 5) 時,我目前得到奇怪的值,例如 )2, 0)當我輸入 5。

#include <iostream>
#include <vector>
#include <math.h>
#include <bits/stdc++.h>

using namespace std;

int main(){

int end_point;
cout << "how many prime numbers would you like to find?\n";
cin >> end_point;

//creates a vector to store all values, that will eventually be whittled down to primes
vector<int> primes = {2};

//adds all numbers between 2 and chosen end point to the vector
for (int i = 3; i <= end_point; i++){

    primes.push_back(i);
}

for (int i = 0; i < end_point; i++){

    //starts at the first value (always 2), and feeds it into the next for loop
    //once the next loop is done, it moves on to the next value in the loop and feeds that in
    primes[i];

    //looks at values in the vector, starting with the next value in the vector
    for (unsigned int j = i+1; j < primes.size(); j++){

        //checks if the value at [j] is divisible by the value at [i]
        //if it is, this deletes it from the vecotr
        //if not, it moves on to the next value in the vector
        if(primes[j] % primes[i] == 0){

            primes.erase (primes.begin() + (j-1));
        }
        else{}
    }

//prints out all of the primes in the specified range
cout << "Primes are: ";
for (unsigned int k = 0; k <= primes.size(); k++){
    cout << primes[k] << ", ";
}
}
}

您可以檢查從 2 到該數字的sqrt的素數。 這將省略重復和額外的檢查。

#include <iostream>
#include <math.h>
#include <vector>

using namespace std;

vector<int> getPrimes(int start, int end){
    if( start <0 || end < 0 || end < start ){
        return {};
    }
    
    int max = 0;
    bool isPrime = true;
    vector<int> prims = {};
    
    
    for( int i = start ; i <= end ; i++ ){
        max = sqrt(i);
        isPrime = true;
        for(int j = 2 ; j <= max ; j++ ){
            if( i % j == 0 ){
                isPrime = false;
                break;
            }
        }
        
        if(isPrime){
            prims.push_back(i);
        }
    }
    
    return prims;
}

int main()
{
    
    
    vector<int> prims = getPrimes(0,100);
    

    
    for(int n : prims) {
        cout << n << '\n';
    }
    
    return 0;
  
}

原因:

假設你想知道 17 是否是質數。 最簡單的方法是從 0 循環到 17 以檢查其倍數。 但它不需要這樣做。 17 的 sqrt 幾乎是 4。所以你檢查倍數,直到數字 4。下一個數字是 5。從 5 到 17,其結果小於 17 的所有倍數是從 4 到 0。因為 5 * 5 是25. 甚至 5 * 4 也是 20。所以所有的倍數都是重復的。 現在您可以檢查從 2 到該數字平方根的倍數,以確定該數字是否為質數

遍歷數組時不應從數組中刪除元素。 您可以通過標記來嘗試。 例子:

#include <iostream>
#include <vector>
#include <math.h>

using namespace std;

int main() {

    int end_point;
    cout << "how many prime numbers would you like to find?\n";
    cin >> end_point;

    //creates a vector to store all values, that will eventually be whittled down to primes
    vector<int> primes = { 2 };

    //adds all numbers between 2 and chosen end point to the vector
    for (int i = 3; i <= end_point; i++) {

        primes.push_back(i);
    }

    for (int i = 0; i < end_point; i++) {

        //starts at the first value (always 2), and feeds it into the next for loop
        //once the next loop is done, it moves on to the next value in the loop and feeds that in
        int val = primes[i];

        // to ensure the value is not zero
        if (val == 0)
            continue;

        //looks at values in the vector, starting with the next value in the vector
        for (unsigned int j = i + 1; j < primes.size(); j++) {

            //checks if the value at [j] is divisible by the value at [i]
            //if it is, this deletes it from the vecotr
            //if not, it moves on to the next value in the vector
            if (primes[j] > 0 && primes[j] % val == 0) {
                // set the value zero to element of array.
                primes[j] = 0;
            }
        }

        //prints out all of the primes in the specified range
        cout << "Primes are: ";
        for (unsigned int k = 0; k <= primes.size(); k++) {
            if (primes[k] > 0) // output the value which greater then zero.
                cout << primes[k] << ", ";
        }
    }

    return 0;
}
  1. 您刪除了錯誤的元素。 這是正確的:

    primes.erase(primes.begin() + j);

  2. 你的最后一個循環在錯誤的地方。 將其從之前的“for 循環”中取出。 而你 go 在最后一個元素之后。 應該:

    k < 素數.size();

不是

k <= primes.size();

=== 現在它可以正常工作了===

#include <iostream>
#include <vector>
#include <math.h>

using namespace std;

int main() {

    int end_point;
    cout << "how many prime numbers would you like to find?\n";
    cin >> end_point;

    vector<int> primes = { 2 };

    for (int i = 3; i <= end_point; i++) {
        primes.push_back(i);
    }

    for (int i = 0; i < end_point; i++) {
        for (unsigned int j = i + 1; j < primes.size(); j++) {
            if (primes[j] % primes[i] == 0) {
                primes.erase(primes.begin() + j);
            }
            else {}
        }
    }
    cout << "Primes are: ";
    for (unsigned int k = 0; k < primes.size(); k++) {
        cout << primes[k] << ", ";
    }
    return 0;
}

暫無
暫無

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

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