[英]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;
}
您刪除了錯誤的元素。 這是正確的:
primes.erase(primes.begin() + j);
你的最后一個循環在錯誤的地方。 將其從之前的“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.