我正在编写一个程序,使用递归在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
。请告诉程序中的错误,而不是编写一个全新的程序。
答案 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筛选(它也很慢但很有趣)和阿特金筛选(快速而有趣但复杂)。