我正在尝试创建一个提示用户输入的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;
}
答案 0 :(得分:1)
你正在研究素数&#34; upto&#34;一个给定的数字N.
在这类问题中,更有效(尽管RAM空间更昂贵)将信息存储在素数和复合数字的表中,如Sieve of Eratosthenes。
一旦你在表格中填写了哪些数字是素数和复合数据的信息,只需要在表格上进行迭代就可以找到孪生素数,无论它们在哪里。
然而,虽然您通知用户所有将显示孪生素数,但实际上您的程序所做的只是尝试显示最新的。
请清楚明确哪个是您的计划的目标。
另一方面,您正在重新定义内部循环内的标识符smallint
,这肯定是一个逻辑错误。
如果你不能使用数组来存储Eratosthenes的Sieve ,那么我在这里向你展示一种不难实现的方法(当然,它并不是最难实现的)有效;但它会避免大量的冗余计算)。
孪生素数(大于4)可以有两种不同的形式:
所以,我会跳入具有6k + 1,6k + 5形式的数字序列,对于k = 0,1,2,3 ......,所以我只会分析中的奇数顺序:
这可以通过添加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;
}