如何使用递归在C中查找素数

时间:2015-07-20 03:17:20

标签: c recursion crash stack-overflow primes

我正在编写一个程序,使用递归在C中查找素数。这是我写的程序。

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

void rec(int, int);
int main()
{
    rec(2,2);
    getch();
    return 0;
}
void rec(int n, int x)
{
    if(x>999)
        return;
    if(n==x)
    {
        printf("%d ,", x);
        rec(2,x+1);
        return;
    }
    if(x%n==0)
    {
        rec(2,x+1);
        return;
    }
    rec(n+1,x);
}

我不知道它有什么问题,它在887之后运行良好。要检查,只需将x>999替换为x>300,它就会起作用,但不适用于x>999。请告诉程序中的错误,而不是编写一个全新的程序。

4 个答案:

答案 0 :(得分:2)

可能超出递归深度。

递归深度似乎与限制的平方成比例 尝试

#include <stdio.h>
int depth = 0;
int maxdepth = 0;

void rec(int n, int x) {
  depth++;
  if (depth > maxdepth) maxdepth = depth;
  if (x > 860) {
    depth--;
    return;
  }
  if (n == x) {
    printf("%d ,", x);
    rec(2, x + 1);
    depth--;
    return;
  }
  if (x % n == 0) {
    rec(2, x + 1);
    depth--;
    return;
  }
  rec(n + 1, x);
  depth--;
}

int main(void) {
  rec(2, 2);
  printf("\n depth %d maxdepth %d\n", depth, maxdepth);
  return 0;
}

最大深度60099(限制为860)

代码需要一种深度不太深入的方法。

尝试将n除以所有素数2到sqrt(n)。如果数为偶数,则仅在2的素数中。否则如果低于7,则如果不是1则为素数。否则找到高于7的素数,将2添加到先前的素数候选者并递归测试它是否为素数。因此,您有2个函数bool is_prime(n)unsigned next_prime(n)互相调用。

最大深度:全部为1000

和OP的self description一样,在这种情况下“太懒了,不能再说些什么。”

答案 1 :(得分:1)

#include<stdio.h>

void rec(int test_number, int prime_index);

int main(void){
    rec(2, 0);

    return 0;
}

void rec(int n, int i){
    static int prime[500], cp;//for memorize
    if(n > 999)
        return;
    if(prime[i] == 0 || prime[i]*prime[i] > n){//prime[i]*prime[i] > n : To reduce the depth of recursion by narrowing the upper limit of the test.
        printf("%d, ", n);
        prime[cp++] = n;
        rec(n + 1 + (n != 2), 0);//n != 2 : Avoid an even number of other than 2
        return;
    }
    if(n % prime[i]==0){
        rec(n + 1 + (n != 2), 0);
        return;
    }
    rec(n, i+1);
}

答案 2 :(得分:0)

您可以尝试使用以下代码查找介于1和给定整数N(范围内的素数列表)之间的素数:

#include<stdio.h>
void main()
{
    int n,flag=0,i,j;
    printf("Enter range of prime number : ");
    scanf("%d",&n);
    printf("\nPrime numbers are : ");
    for(i=1;i<n;i++)
    {
        flag=0;
        for(j=2;j<i;j++)
        {
            if(i%j==0)
            {
                flag=1;
                break;
            }
            else
                flag=0;
        }
        if(flag==0)
            printf("\n%d",i);
    }
}

答案 3 :(得分:0)

问题:在不同条件语句下多次递归rec函数会导致递归深度增加。

解决方案:通过在main函数中使用循环来在rec函数中检查(素数与否)下减少条件语句下rec函数的使用。

#include<stdio.h>
void rec(int,int);
int main()
{
    int i=2;
    while(i<=1000) //passing 2,3,4...,1000 (one by one) in rec function to check if it is prime or not
    {
        rec(2,i);
        i++;
    }
}
void rec(int n,int x)
{
    if(n==x) //if number(n) by which divisibility is checked and number(x or i) which is under checking gets equal then number(x or i) is proved as prime and get printed
        printf("%d, ", x);
    else if(x%n!=0) //if number(x or i) under checking is not divisible by number(n) then call rec function again to check divisibility of number(x) by number(n+1)
        rec(n+1,x);
//if number(x or i) under checking is divisible by number(n) at any stage then return to main function and next number(i++ or new x) is passed to rec function to check if it is prime or not
}

建议:递归函数很有意思。但是使用递归函数或任何简单方法将质数打印到像(10 ^ 6)这样的大限制是非常慢的。使用 Eratosthenes筛选(快速,简单和有趣)或一些修改版本(最快)来非常快速地打印素数。还要尝试学习 Sundaram筛选(它也很慢但很有趣)和阿特金筛选(快速而有趣但复杂)。