寻找最大的Twin Prime

时间:2015-08-05 04:02:55

标签: c

我正在尝试创建一个提示用户输入的c程序,然后找到该数字中最大的孪生素数。该程序然后连续循环,一次又一次地提示用户输入并找到最大的孪生素数直到用户输入-1,之后它终止。我写下了基本代码,但是在使用某些数字(例如20和65)时,它仍然可以连续循环。我无法弄清楚我的代码有什么问题。

我似乎也遇到了另一个问题。对于20,值显示(15,17)而不是(17,19)。显然逻辑在某处是错误的,但我不确定究竟在哪里。

这是我的代码:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include<conio.h>

int prime(int x)
{
    int i,numroot;
    numroot=sqrt(x);
    for(i=2;i<=numroot;i++)
    if(x%i==0){
        return(0);
    }
    return(1);

}

int main()
{
    double N;

    printf("This program prints out all the possible twin primes until a specific number which...\nyou can choose!");
    printf("\nA note of caution: Although this program accepts decimals, the value entered must be between 5 and 10^9,inclusive of the 2 numbers.");
    printf("\nKey in -1 to exit.");
    printf("\nEnter N value upto which twin primes ought to be calculated until: ");
    scanf("%lf",&N);

    while (N!=-1) {
      if (N<5 || N>pow(10,9)) {
          printf("\nNumber not in the valid range was inputted. \nPlease reenter the value: ");
          scanf("%lf",&N);
      }
      else {
          int n;
          n=floor(N);
              int prime(int x);
          int f,originalval;

          originalval=N;
          f=prime(n);
          while(f==0){//Calculates for largest prime number below user input
            n--;
            f=prime(n);
          }
          int smallint=n-2;
          while(prime(smallint)==1){
              n--;
              f=prime(n);
              while(f==0){
                  n--;
                  f=prime(n);
              }
              int smallint=n-2;
    }
    printf("The largest twin prime pair not above %d is (%d,%d)",originalval,smallint,n);
          printf("\nPlease re-enter the value:");
          scanf("%lf",&N);
      }
    }
    printf("\nProgram successfully terminated.");
    return 0;
}

2 个答案:

答案 0 :(得分:1)

你正在研究素数&#34; upto&#34;一个给定的数字N.
在这类问题中,更有效(尽管RAM空间更昂贵)将信息存储在素数和复合数字的表中,如Sieve of Eratosthenes

一旦你在表格中填写了哪些数字是素数和复合数据的信息,只需要在表格上进行迭代就可以找到孪生素数,无论它们在哪里。

然而,虽然您通知用户所有将显示孪生素数,但实际上您的程序所做的只是尝试显示最新的。

请清楚明确哪个是您的计划的目标。

另一方面,您正在重新定义内部循环内的标识符smallint,这肯定是一个逻辑错误。

如果你不能使用数组来存储Eratosthenes的Sieve ,那么我在这里向你展示一种不难实现的方法(当然,它并不是最难实现的)有效;但它会避免大量的冗余计算)。

孪生素数(大于4)可以有两种不同的形式:

  • 6k-1,6k + 1
  • 6k + 1,6k + 5

所以,我会跳入具有6k + 1,6k + 5形式的数字序列,对于k = 0,1,2,3 ......,所以我只会分析中的奇数顺序:

  • 5,7,11,13,17,19,23,25,29,31,35,37,41,43,47,49,......

这可以通过添加2,然后是4,然后是2,然后是4,然后是2,然后是4来获得...

所以,可以拿第一对,让我们说5和7 我们将它们分成6k + 1和6k + 5形式的奇数,小于它们中最大的平方根(sqrt(7))。
如果较小的数字(在这种情况下为5)可以被某个数字整除,我们在列表中选择以下数字,即11,并将其除以目前用于测试7是否为素数的所有数字。从这一点开始,我们将7和11之间的剩余数字除以sqrt(11),依此类推。

请注意,对于大数字,6k + 1和6k + 5具有非常相似的平方根。

如果相反的情况发生,也就是说,对于那对(5,7),该对的最大元素(在这种情况下:7)可被其他数字整除,那么我们就丢弃它们(5) 7)并选择列表的以下两个元素(在这个例子中将是11和13)。因此,我们从头开始搜索(即通过小数除)。

最后,如果循环结束而没有为这对夫妇的任何元素找到除数(这确实是6和7的情况),那么我们可以告知这对夫妻是孪生素数。
(或者我们可以保持沉默)。

然后,我们丢弃最小元素(在这种情况下:5)并保留最大元素(在这种情况下:7)。
由于我们已经知道7是素数,我们只选择上面列表中的以下元素(在本例中为11),并仅搜索它的除数。

我认为我所解释的方法会避免大量的冗余计算。

此外,有必要保持最新更新的两对孪生素数。我认为没有必要向你解释如何做到这一点。

答案 1 :(得分:0)

我们应该促使这两个数字都是素数。区别之间是2。如你所知,首先孪生素数为(3,5)。我还没有找到符合我预期的配方。所以,我已经使用迭代来解决问题。如果你查看代码,就可以理解。

#include <stdio.h>
#include <math.h>

int twinPrime(int m);
int IsPrime(unsigned int number);


int main()
{
    double N;
    int floored;
    int prime;

    printf("This program prints out all the possible twin primes"
           "until a specific number which...\nyou can choose!");
    printf("\nA note of caution: Although this program accepts decimals, "
           "the value entered must be between 5 and 10^9,inclusive of the 2 numbers.");
    printf("\nKey in -1 to exit.");
    printf("\nEnter N value upto which twin primes ought to be calculated until: ");
    scanf("%lf",&N);

    while (N != -1)
    {
        if (N < 5 || N > pow(10,9))
        {
            printf("\nNumber not in the valid range was inputted. \n"
                   "Please reenter the value: ");
            scanf("%lf",&N);
        }
        else
        {
            floored = floor(N);
            prime = twinPrime(floored);
            printf("The largest twin prime pair not above %d is (%d,%d)",floored,prime - 2,prime);
            printf("\nPlease re-enter the value:");
            scanf("%lf",&N);
        }
    }
    printf("\nProgram successfully terminated.");
    return 0;
}

int twinPrime(int m)
{
    int p = 3;
    int q = 5;

    for (; q < m - 1; q += 2)
    {
        if (IsPrime(q))
        {
            if (q - p == 2)
            {
                continue;
            }
            p = q;
        }
    }
    return q;
}

int IsPrime(unsigned int number)
{
    if (number <= 1) return 0; // zero and one are not prime
    if ((number > 2) && ((number % 2) == 0)) return 0; //no even number is prime number (bar 2)
    unsigned int i;
    for (i=2; i*i<=number; i++)
    {
        if (number % i == 0) return 0;
    }
    return 1;
}