打印质数的程序

Program that prints prime numbers

使用递归从用户打印给定范围内的 2 个最大素数的程序。 我想获得用户给定范围内的 2 个最大素数,但不知何故它只是打印该范围内的连续数字。当我构建一个程序时,我的代码中的质数检查器正在工作,该程序要求用户输入结束数,检查它是否是质数并打印从 1 到 n 的所有质数。但是当我将它插入这段代码时,它运行不正常。我尝试研究其他代码作为我的参考,但我找不到任何打印 2 个最大素数的代码。用户输入的是不是素数并不重要,代码只会检查中间两个最大的素数。如果结束数或 y 是素数,也可以打印它。我也在尝试不使用数组来练习我的参数传递。

在这段代码中,我尝试获取 2 个最大的素数并打印出来。可以看到num1和num2没有用到,它们应该是给定范围内2个最大素数的变量。

#include <stdio.h>

void usersInput(int *x, int *y);
void swapping(int *x, int *y);
int primeCheck(int i, int j);

int main() {
    int x, y, i, j, num1, num2;
    
    usersInput(&x, &y);

    if (x > y) {
        swapping(&x, &y);
    }

    printf("The value of x is %d, and the value of y is %d.\n", x, y);

    printf("\nThe two largest prime numbers from %d to %d are : ", x, y);
    for (i = x; i <= y; i++)
        if (primeCheck(i, y) == 0)
            printf("%d ", i);

    return 0;
}

void usersInput(int *x, int *y) {

    printf("Enter the value of x: ");
    scanf("%d", x);
    printf("Enter the value of y: ");
    scanf("%d", y);
}

void swapping(int *x, int *y) {
    int temp;
    temp = *x;
    *x = *y;
    *y = temp;
}

int primeCheck(int i, int j) {
    if (j == i) {
        return 0;
    } else if (j % i == 0) {
        return 1;
    } else {
        return primeCheck(i + 1, j);
    }
}

如您所见,我还没有任何函数可以获取 2 个最大的素数。我真的不知道该怎么做,所以请帮助我

这是实际输出:

Enter the value of x: 10
Enter the value of y: 3
The value of x is 3, and the value of y is 10.
The two largest prime numbers from 3 to 10 are: 6 7 8 9 10

这是预期的输出

Enter the value of x: 10
Enter the value of y: 3
The value of x is 3, and the value of y is 10.
The two largest prime numbers from 3 to 10 are: 5 7

这个if语句的sub-statement就是printf的调用:

 if (primeCheck(i,y)==1)
            printf("%d ", i);

在函数primeCheckreturns1.

时获取控件

但是根据函数定义 returns 1y 可以被 [i, y] 范围内的任何数字整除并且这个数字不是必须的是 i:

} else if (j%i==0) {
    return 1;

在所有其他情况下函数 returns 0.

由于函数递归调用自身,因此当至少 [x, y] 范围内的一个数 y 可被该数整除时,它 returns 1。

例如,对于您的输入,如果范围 [3, 5],函数总是 return 1,因为 10 可以被 5 整除。

实际上你的函数没有意义,与素数没有共同之处。

还要注意,要在一个范围内找到两个最大的质数,你应该从最大的数开始循环到范围内的最小数。

我认为您对作业的理解不正确。看来您需要编写 non-recursive 函数来确定给定数字是否为素数,并编写递归函数而不是 return 两个最大素数的 for 循环。

即递归查找两个最大质数的函数,如下面的演示程序所示:

#include <stdio.h>

struct TwoPrimes
{
    unsigned int first_prime;
    unsigned int second_prime;
};

int is_prime( unsigned int n );

struct TwoPrimes find_two_primes( unsigned int first, unsigned int last )
{
    if (first == last)
    {
        struct TwoPrimes two_primes = { ( is_prime( first ) ? last : 0 ), 0 };
        return two_primes;
    }
    else
    {
        struct TwoPrimes two_primes = find_two_primes( first + 1, last );

        if (two_primes.first_prime == 0 || two_primes.second_prime == 0)
        {
            if (is_prime( first ))
            {
                if (two_primes.first_prime == 0)
                {
                    two_primes.first_prime = first;
                }
                else
                {
                    two_primes.second_prime = first;
                }
            }
        }

        return two_primes;
    }
}

int main( void )
{
    struct TwoPrimes two_primes = find_two_primes( 3, 10 );

    if (two_primes.first_prime != 0)
    {
        printf( "%u\n", two_primes.first_prime );

        if (two_primes.second_prime != 0)
        {
            printf( "%u\n", two_primes.second_prime );
        }
    }
}

你需要自己做的是定义函数is_prime

您的代码中存在多个问题:

  • 素数测试 if (primeCheck(i, y) == 0) 不正确:您应该将 2 作为第一个参数传递,将 i 作为第二个参数传递。
  • 循环应该从 i = y 和 运行 开始,而 i >= x,递减 i 以首先找到范围内的最大素数。
  • 你应该存储质数并在找到 2 个时停止。
  • 素数测试函数应修改为return 1 if i > j 以防止某些输入的无限递归,例如primeCheck(2, 1).
  • primeCheck() 中测试直到并包括 sqrt(j) 的除数就足够了。您可以在 j < i * i 时停止递归,这可以在没有潜在溢出的情况下进行测试,如 j / i < i.

这是您的代码的修改版本:

#include <stdio.h>

int usersInput(int *x, int *y);
void swapping(int *x, int *y);
int primeCheck(int i, int j);

int main() {
    int x, y, i, num1, num2;
    
    if (!usersInput(&x, &y)) {
        return 1;
    }
    if (x > y) {
        swapping(&x, &y);
    }

    printf("The value of x is %d, and the value of y is %d.\n", x, y);

    for (i = y, num1 = num2 = 0; i >= x; i--) {
        if (primeCheck(2, i) == 0) {
            if (num2 == 0) {
                num2 = i;
            } else {
                num1 = i;
                break;
            }
        }
    }
    printf("The two largest prime numbers from %d to %d are: %.0d %.0d\n",
            x, y, num1, num2);
    return 0;
}

// read user input return zero on failure
int usersInput(int *x, int *y) {
    printf("Enter the value of x: ");
    if (scanf("%d", x) != 1)
       return 0;
    printf("Enter the value of y: ");
    return scanf("%d", y) == 1;
}

void swapping(int *x, int *y) {
    int temp = *x;
    *x = *y;
    *y = temp;
}

int primeCheck(int i, int j) {
    if (j < 2) {
        return 1;  // negative, 0 or 1: not prime
    } else if (j / i < i) {
        return 0;  // all factors tested up to sqrt(j): j is prime
    } else if (j % i == 0) {
        return 1;  // composite, not prime
    } else {
        return primeCheck(i + 1, j);
    }
}

输出:

Enter the value of x: 10
Enter the value of y: 3
The value of x is 3, and the value of y is 10.
The two largest prime numbers from 3 to 10 are: 5 7