【问题标题】:How do I put prime numbers into a vector?如何将素数放入向量中?
【发布时间】:2016-01-07 10:51:34
【问题描述】:

我在下面写了一段代码,它要求用户输入并检查它是否是素数。我现在想以此为基础,所以当用户输入一个数字时,我会计算到这个数字的素数并显示。例如,如果用户输入 10,我的程序将输出“有 4 个素数”。我的想法是我必须将每个素数存储到一个向量中,但我的问题是如何?

#include <iostream>
#include <cmath>
#include <vector>
using namespace std;

int main()
{
    vector <double> primeHolder
    int x, i, flag;
    cout << "Enter a positive integer ";
    cin >> x;

    for (i = 2; i <= x/2; i++)
    {
        if(x%i == 0)
        {
            flag = 1;
            break;
        }
    }

    if (flag == 0)
        cout << "This is a prime number";
    else
        cout << "This is not a prime number";
    return 0;
}

【问题讨论】:

  • 使用循环和push_back(x)?
  • 首先,x/2 有点过分(使用i &lt;= sqrt(x))。其次,eratosthene's sieve 效率更高(特别是如果在布尔掩码中,您每比特只保存奇数,当您增加*尺寸时甚至更多)。第三,push_back() 是你需要的。
  • 使用费马素数检验,1 / (2^100) 可能会出错,您可以更快地完成:en.wikipedia.org/wiki/Fermat_primality_test

标签: c++ vector


【解决方案1】:

首先,定义isPrime() 函数以使您的代码更具可读性是有意义的:

bool isPrime(int x)
{
    for(int i = 2; i <= x/2; i++)
    {
        if(x%i == 0)
        {
            return false;
        }
    }
    return true;
}

然后你可以用下面的方式写你的main()

int main()
{
    int input;
    cout << "Enter a positive integer: ";
    cin >> input;

    // You deal with integers here, so you shouldn't use vector<double>.
    // As all numbers are positive, you could also use unsigned int.
    vector<int> primeHolder;
    for(int i = 2; i <= input; i++)
    {
        // Test all values that are not larger than the input value.
        if(isPrime(i))
        {
            // If the tested value is a prime, append it to the vector.
            primeHolder.push_back(i);
        }
    }

    cout << "There are " << primeHolder.size() << " primes:" << endl;
    for(size_t j = 0; j < primeHolder.size(); j++)
    {
        // Print every prime number that was stored in the vector.
        // You can access vector elements similar to an array,
        // but you can also use iterators.
        cout << primeHolder[j] << endl;
    }
    return 0;
}

此代码为您的示例输入提供以下输出:

输入一个正整数:10
有 4 个素数:
2
3
5
7

注意:上面的代码效率很低。如果您想处理大量输入,您应该寻找更智能的算法,例如Sieve of Eratosthenes,正如 @theoden 在 cmets 中提到的那样。

如果您想了解更多关于vector 类模板的功能,请查看documentation。该文档还包含示例代码。

【讨论】:

  • 谢谢鸣人!正是我想要的。只是一个简单的问题,当您使用 for(size_t j=0; .....
  • size() 函数的vector 提供size_t 类型的值。这是一个无符号值。如果我将int 用于j,那么我的编译器会警告我signedunsigned 之间存在冲突。所以,如果你使用size_t,你是安全的。
  • 谢谢鸣人!非常有帮助:)
【解决方案2】:

在 if 语句中你发现它是一个素数,只需将它添加到向量中。

小示例代码:

if(x is prime)
{
    primeHolder.push_back(x);
}

【讨论】:

  • 谢谢 Tarik,但这里的 'push_back(x)' 是什么?
  • 这就是将事物添加/插入向量的方式。您可以在此处阅读向量的所有功能 - link,专门查找 push_back
  • 好吧,这样就可以用素数填充向量了。现在,如果我想打印这个向量,我只需使用 cout
  • @FrankWhite 请参考书籍或教程,Stack Overflow 不是一个辅导网站。
  • @FrankWhite 在google上输入很简单,“如何打印出一个向量c++”。您不需要在此处创建线程。您可以轻松地在 Google 上搜索“如何添加到矢量”或类似内容。
【解决方案3】:

由于向量包含素数,最好通过将当前数字除以向量中的元素来确定下一个素数。

程序可以如下所示

#include <iostream>
#include <functional>
#include <algorithm>
#include <vector>

int main()
{
    while ( true )
    {
        std::cout << "Enter a non-negative number (0-exit): ";

        unsigned int n = 0;
        std::cin >> n;

        if ( !n ) break;

        std::vector<unsigned int> primes;

        if ( n >= 2 ) primes.push_back( 2 );

        for ( unsigned int i = 3; i <= n; i += 2 )
        {
            if ( std::all_of( primes.begin(), primes.end(), std::bind1st( std::modulus<unsigned int>(), i ) ) )
            {
                primes.push_back( i );
            }
        }

        if ( !primes.empty() )
        {
            std::cout << "There are the following prime numbers up to " << n << ": ";
            for ( unsigned int x : primes ) std::cout << x << ' ';
            std::cout << std::endl;
        }
        else
        {
            std::cout << "There are no prime numbers up to " << n << std::endl;
        }           
    }

    return 0;
}

如果按顺序输入以下数字

10 20 30 40 50 60 70 80 90 100 0

那么程序输出会是这样的

Enter a non-negative number (0-exit): 10
There are the following prime numbers up to 10: 2 3 5 7 
Enter a non-negative number (0-exit): 20
There are the following prime numbers up to 20: 2 3 5 7 11 13 17 19 
Enter a non-negative number (0-exit): 30
There are the following prime numbers up to 30: 2 3 5 7 11 13 17 19 23 29 
Enter a non-negative number (0-exit): 40
There are the following prime numbers up to 40: 2 3 5 7 11 13 17 19 23 29 31 37 
Enter a non-negative number (0-exit): 50
There are the following prime numbers up to 50: 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 
Enter a non-negative number (0-exit): 60
There are the following prime numbers up to 60: 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 
Enter a non-negative number (0-exit): 70
There are the following prime numbers up to 70: 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 
Enter a non-negative number (0-exit): 80
There are the following prime numbers up to 80: 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 
Enter a non-negative number (0-exit): 90
There are the following prime numbers up to 90: 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 
Enter a non-negative number (0-exit): 100
There are the following prime numbers up to 100: 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97 
Enter a non-negative number (0-exit): 0

【讨论】: