【问题标题】:Printing n pairs of prime numbers, C++打印 n 对素数,C++
【发布时间】:2017-05-03 16:50:26
【问题描述】:

我需要编写一个程序来打印 n 对素数,这些对是:

pq

其中 p 和 q 是素数,q = p+2。

输入示例:

n = 3

3 5 // 5 7 // 11 13 //

我几乎还是无处可去……那么,有人吗?

#include <iostream>
#include <cmath>

int twins(int n)
{
    for (int i = 0; i < n; i++)
    {
        ???
     }
}

int main()

{
    std::cout<<twins(5);
    return 0;
}

【问题讨论】:

  • 鉴于您需要编写多个数字,因此只能打印一个数字的设计从一开始就似乎是一条死胡同。
  • 还有,您的素数检测算法在哪里?我敢打赌,你可以很容易地在网上找到一个。然后,只需对其进行调整,只检测素数对。

标签: c++


【解决方案1】:

这是这种野兽的顶级简单伪代码:

def printTwinPrimes(count):
    currNum = 3
    while count > 0:
        if isPrime(currNum) and isPrime(currNum + 2):
            print currnum, currnum + 2
            count = count - 1
        currNum = currNum + 2

它只是从3 开始(因为我们知道2,4 不可能作为双质数对,因为4 是复合数)。对于每一种可能性,它都会检查它是否构成双质数对,如果是则打印出来。

所以您需要做的(除了将其翻译成真实代码)就是创建isPrime(),网上有无数的例子。

为了完整起见,这里有一个简单的,绝不是最有效的,但对初学者来说已经足够了:

def isPrime(num):
    if num < 2:
        return false
    root = 2
    while root * root <= num:
        if num % root == 0:
            return false
        root = root + 1
    return true

虽然您可以通过使用除两个或三个以外的所有素数都采用6n±1, n &gt;= 1(a) 的形式这一事实来提高效率:

def isPrime(num):
    if num < 2: return false
    if num == 2 or num == 3: return true
    if num % 2 == 0 or num % 3 == 0: return false
    if num % 6 is neither 1 nor 5: return false

    root = 5
    adder = 2                   # initial adder 2, 5 -> 7
    while root * root <= num:
        if num % root == 0:
            return false
        root = root + adder     # checks 5, 7, 11, 13, 17, 19, ...
        adder = 6 - adder       # because alternate 2, 4 to give 6n±1
    return true

实际上,您可以使用这种除法技巧来查看存储为字符串的任意大数是否可能是素数。你只需要检查它下面或上面的数字是否能被六整除。如果不是,这个数字肯定不是素数。如果是这样,则需要更多(更慢)的检查来完全确定素数。

一个数只能被 2 和 3 整除,才能被 6 整除。前者很容易看出,偶数以偶数结尾。

但也很容易判断它是否可以被 3 整除,因为在这种情况下,各个数字的总和将 被 3 整除。例如,让我们使用31415926535902718281828459

所有这些数字的总和是118。我们如何判断那是是三的倍数?为什么,递归使用完全相同的技巧:

118: 1 + 1 + 8 = 10
 10: 1 + 0     = 1

当您减少到一位数时,如果原始数字是三的倍数,它将是 0369。任何其他数字都表示它不是(例如在这种情况下)。


(a) 如果将任何非负数除以 6,余数为 0、2 或 4,则它是偶数,因此非质数(2 是这里的例外情况):

6n + 0 = 2(3n + 0), an even number.
6n + 2 = 2(3n + 1), an even number.
6n + 4 = 2(3n + 2), an even number.

如果余数是 3,那么它可以被 3 整除,因此是非质数(3 是这里的例外情况):

6n + 3 = 3(2n + 1), a multiple of three.

只剩下余数 1 和 5,这些数字都是 6n±1 的形式。

【讨论】:

  • 谢谢! :) :) :)
【解决方案2】:

可能不是最有效的,但您可以计算直到 n 的所有素数,将它们存储在一个向量中,然后只打印那些差为 2 的素数

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

void pr(int n, vector<int>& v)
{
    for (int i=2; i<n; i++) 
    {
        bool prime=true;
        for (int j=2; j*j<=i; j++)
        {
            if (i % j == 0) 
            {
                prime=false;
                break;    
            }
        }   
        if(prime) v.push_back(i);
    }
}
int main()
{
   vector<int> v;
   pr(50, v);
   for(int i = 0;i < v.size()-1; i++) {
       if(v[i+1]-v[i] == 2) {
           cout << v[i+1] << " " << v[i] << endl;
       }
   }

   return 0;
}

【讨论】:

    【解决方案3】:

    我认为这是对您来说有效且易于理解的算法。您可以根据您的约束更改 k 的值。

    #include <iostream>
    #include <cstring>
    using namespace std;
    
    int n,p=2,savePrime=2,k=100000;
    
    void printNPrime(int n)
    {
        bool prime[k];
        memset(prime, true, sizeof(prime));
    
       while(n>0)
       {
            if (prime[p] == true)
            {
                if(p-savePrime == 2)
                {
                    cout<<savePrime<<" "<<p<<endl;
                    n--;
                }
                // Update all multiples of p
                for (int i=p*2; i<=k; i += p)
                    prime[i] = false;
                savePrime=p;    
            }
          p++;  
       }
    
    }   
    
    int main() {
        cin>>n;
        printNPrime(n);
        return 0;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-02-16
      • 2017-03-06
      • 2012-03-26
      • 1970-01-01
      • 2013-03-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多