[英]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.