程序检查一个数字是否可以表示为两个质数之和

时间:2018-09-05 18:57:35

标签: c primes

我编写了以下程序来检查给定数字是否可以表示为两个质数之和。它可以编译,但不能按预期工作。例如,对于输入= 16,它显示16不能表示为两个质数之和。同样对于输入= 5,它显示5 = 3 + 2而不是5 = 2 + 3。

/* Program to check whether a number can be expressed as a sum of two prime numbers*/
#include <stdio.h>
#include <stdlib.h>

int prime(int x)
{
    int fact=0,i;
    for(i=2;i<x;i++)
    {
        if(x%i==0)
        {
            fact++;
            break;
        }
    }
    if (fact==0)
        return 1;
    else return 0;
}
int main()
{
    int a,b,c,d,count=0;
    printf("Enter Number\n");
    scanf("%d",&a);
    for(b=2;b<(a+1)/2;b++);
    {
        c = prime(b);
        d = prime(a-b);
        if (c==1 && d==1)
        {
            printf("%d = %d + %d\n",a,b,a-b);
            count++;
        }
    }
    if(count==0)
        {
            printf("%d cannot be expressed as sum of two prime numbers.\n",a);
        }
    return 0;
}

4 个答案:

答案 0 :(得分:4)

您的代码中有两个错误:

在函数prime()中,您无需检查x的值2,它也是素数。

第二个错误是在;语句之后的for

for(b=2;b<(a+1)/2;b++);

将其删除,否则以下循环块({}之间的部分)不会在每次循环迭代时执行,而只会在循环结束之后执行。

通常,您不需要读取浮点数,而需要一个整数。将fgets()atoi()用于您的用例。它们比scanf()安全得多。

最后一点:在运算符之前和之后添加空格。这使代码更具可读性。

完整代码

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

int prime(int x)
{
    int i;

    if (x == 2)
    {
        return 1;
    }

    for (i = 2; i < x; i++)
    {
        if (x % i == 0)
        {
            return 0;
        }
    }

    return 1;
}

int main()
{
    int read_number;
    int summand1;
    int summand2;
    int count = 0;
    int max;
    char buffer[100];

    printf("Enter Number\n");
    fgets(buffer, sizeof(buffer), stdin);
    read_number = atoi(buffer);

    max = (read_number + 1) / 2;

    for (summand1 = 2; summand1 < max; ++summand1)
    {
        summand2 = read_number - summand1;
        if ((prime(summand1) == 1) && (prime(summand2) == 1))
        {
            printf("%d = %d + %d\n", read_number, summand1, summand2);
            count++;
        }
    }

    if (count == 0)
    {
        printf("%d cannot be expressed as sum of two prime numbers.\n", read_number);
    }

    return 0;
}

当然,您可以进行一些优化。例如在prime()中:如果您已经检查过x不是2的倍数,则可以从3开始循环,然后将i增加2反复进行。或者,如果i大于x的平方根,则可以停止此循环。这些措施可能会加快大量代码的速度,但可能会使代码的可读性降低。这是您必须考虑的折衷方案,特别是如果您开始学习编程的话。

答案 1 :(得分:1)

这是更正的代码:

/* Program to check whether a number can be expressed as a sum of two prime numbers*/
#include <stdio.h>
#include <stdlib.h>

int prime(int x)
{
    int fact=0,i;
    if(x < 2) return 0;
    for(i=2;i<x;i++)
    {
        if(x%i==0)
        {
            fact++;
        }
    }
    if (fact==0)
        return 1;
    else return 0;
}
int main()
{
    int a;
    int b,c,d,count=0;
    printf("Enter Number\n");
    scanf("%d",&a);
    for(b=2;b<(a+1)/2;b++)//;mistake here!!
    {
        c = prime(b);
        d = prime(a-b);
        if (c==1 && d==1)
        {
            printf("%d = %d + %d\n",a,b,a-b);
            count++;
        }
    }
    if(count==0)
        {
            printf("%d cannot be expressed as sum of two prime numbers.\n",a);
        }
    return 0;
}

主要问题是,您使用半列;结束了循环。另一个建议是在各处使用int类型。

答案 2 :(得分:1)

请注意,其他人已经捕获了您的错误,但是由于您要求优化的版本,因此该版本的运行速度会更快。

prime函数仅转到sqrt(x),并且仅查看主循环中的奇数值。另外,在main中,循环仅查看奇数值。

/* Program to check whether a number can be expressed as a sum of two prime
numbers*/
#include <stdio.h>
#include <stdlib.h>

int
prime(int x)
{
    int pflg = 1;
    int sqr;
    int i;

    // 2,3 are prime
    if (x <= 3)
        return (x >= 2);

    // even numbers are not
    if ((x & 1) == 0)
        return 0;

    // get sqrt(x)
    for (sqr = 0;  (sqr * sqr) < x;  ++sqr);

    // we only need to check odd numbers
    for (i = 3; i <= sqr; i += 2) {
        if (x % i == 0) {
            pflg = 0;
            break;
        }
    }

    return pflg;
}

int
main()
{
    int a,
     b,
     a2,
     count = 0;

    printf("Enter Number\n");
    scanf("%d", &a);

    a2 = (a + 1) / 2;

    // check when b is 2
    b = 2;
    if (b < a2) {
        // NOTE: if prime(b) is 0, no need to calculate prime(a - b)
        if (prime(b) && prime(a - b)) {
            printf("%d = %d + %d\n", a, b, a - b);
            count++;
        }
    }

    // only odd b values can be prime
    for (b = 3; b < a2; b += 2) {
        // NOTE: if prime(b) is 0, no need to calculate prime(a - b)
        if (! prime(b))
            continue;
        if (! prime(a - b))
            continue;
        printf("%d = %d + %d\n", a, b, a - b);
        count++;
    }

    if (count == 0) {
        printf("%d cannot be expressed as sum of two prime numbers.\n", a);
    }

    return 0;
}

请注意,在main中,if (prime(b) && prime(a - b)使用所谓的“短路评估”。这意味着如果prime(b)返回0,prime(a - b)被调用/求值,因为0 && whatever可以从不为非零< / p>

答案 3 :(得分:0)

你可以参考这个简单的代码。

#include <stdio.h>
int check_Prime(int s)
{
    int flag = 0;
    for (int k = 2; k < s; k++)
    {
        if (s % k == 0) {
            flag = 1;
            break;
        }
    }
    if (flag == 0)
        return 1;
    else
        return 0;
}
int main()
{
    int n, i, j;
    printf("Enter the number : ");
    scanf("%d", &n);
    for (i = 1, j = n - 1; i < n / 2, j >= n / 2; i++, j--) {
        int a = check_Prime(i);
        int b = check_Prime(j);
        if (a == 1 && b == 1) {
            printf("%d = %d + %d\n", n, i, j);
        }
    }
}

考虑如果输入是 34,变量 i 的取值范围为 1 到 34/2=17,而 j 的取值范围为 34-1=33 到 17。

所以对应的和 i+j 变成了

1+33,i 加 1,j 减 1

2+32

3+31......

现在通过函数 check_Prime 检查对应的 i 和 j 是否为素数,如果是则显示。