C- Fix Stack overflow in Recursion - c

A code in C to find maximum of an array using divide and conquer but it keeps throwing
"stack overflow exception" . Help would be appreciated!
int a[10];
int find(int l,int h)
{
int x;
if(h==0)
{
x=0;
return x;
}
else
{
if(h==1)
{
if(a[0]>a[1])
{
x=0;
return x;
}
else
{
x=1;
return x;
}
}
else
{
int mid,z,y;
mid=(l+h)/2;
y=find(0,mid);
z=find(mid+1,h);
if(a[y]<a[z])
{
x=z;
}
else
{
x=y;
}
return x;
}
}
}
There are only limited variables and I don't see where the function can go into an infinite recursion.
int main()
{
int i,n,max,min,ans;
scanf("%d",&n);
for(i=0;i<n;i++)
{
scanf("%d",&a[i]);
}
ans=find(0,n-1);
printf("the maximum element is- %d\n",ans);
getch();
return 0;
}

Consider the case where you call find(0, 2). Since h > 1, you enter the second else clause, and mid is 1. Then on the second recursive call, it is to find(2, 2). On this recursive call, you again enter the second else, since h is still 2. But the mid is also 2. Now, the first recursive call goes to find(0, 2), which enters an infinite loop.
find(0, 2)
h not 0
h not 1
mid = 1
find(0, 1)
find(2, 2)
h not 0
h not 1
mid = 2
find (0, 2) <-- loop
It seems the intention of the if checks on h is to prevent the mid calculation from being the same as l. If so, then you can calculate the mid variable at the top of your function, and use that as the stopping condition.
It looks like this is an attempt to use divide and conquer to locate the position of the maximum element in the array a. If so, then your first recursive call should restrict itself to the range of [l..mid] instead of going back to 0.
Putting it all together:
int find(int l,int h)
{
int mid = (l+h)/2;
if (mid == l)
{
return (a[l] > a[h]) ? l : h;
}
else
{
int y = find(l, mid);
int z = find(mid+1, h);
return (a[y] > a[z]) ? y : z;
}
}

Here is your code modified, which is running successfully..
The problem is that you weren't checking the difference between l and h but only the value of h...
#include <iostream>
using namespace std;
int a[10];
int find(int l,int h)
{
int x;
if(h-l==0)
{
return h;
}
else
{
if(h-l==1)
{
if(a[l]>a[l+1])
{
return l;
}
else
{
return l+1;
}
}
else
{
int mid,z,y;
mid=(l+h)/2;
y=find(0,mid);
z=find(mid+1,h);
if(a[y]<a[z])
{
x=z;
}
else
{
x=y;
}
return x;
}}}
int main()
{
a[0]=3;
a[1]=7;
a[2]=5;
cout<<find(0,2)<<endl;
return 0;
}

you're using wrong conditions, try:
first if: if(h==l)
second if: if(h-l==1)
third if:
if(a[h]>a[l]) {
return h;
} else {
return l;
}

Related

Program that computes the nth element of a number series given by a formula

Write a method/function with name cpSeries that computes the nth element in a series of numbers, given by the formula: a(n) = (a(n-1))2+a(n-2) when: n>1 and assuming that: a(1)=1, a(0)=0 Note that indexing of the series starts from 0.
I have already written the above code but it runs for an infinite time and I don't know how to fix it in order to compute the nth element.
Any ideas? I have to use only functions to solve this problem.
# include <stdio.h>
int cpSeries(int n)
{
int Nthterm = 0;
int i;
if (n==0) {
cpSeries(0) == 0;
}
else if (n==1) {
cpSeries(1) == 1;
}
for (i=0; i<=n; i++){
Nthterm = cpSeries((n-1))*cpSeries((n-1)) + cpSeries((n-2));
return Nthterm;
}
}
int main()
{
int n=6;
printf("The Nth term of the series is: %d",cpSeries(n));
}
If the provided equation gives you the nth element, I don't see the need for a loop.
Also, in the if conditions, you are calling the function again, but what you should do is return the value you need.
int cpSeries(int n){
int Nthterm;
if (n==0){
Nthterm = 0;
}
else if (n==1){
Nthterm = 1;
}
else {
Nthterm = cpSeries((n-1))*cpSeries((n-1)) + cpSeries((n-2));
}
return Nthterm;
}
Your final conditions just call the function another time instead of returning 0 or 1.
instead of
if (n==0) {
cpSeries(0) == 0;
}
else if (n==1) {
cpSeries(1) == 1;
}
use
if (n==0) {
return 0;
}
else if (n==1) {
return 1;
}
C is not a declarative language where you can specify the return value y of a function f given an argument x by writing something like f(x) = y, but you have to use a return statement.
Change cpSeries(0) == 0; to
return 0;
to avoid the infinite recursion (and the same for n == 1).

C Recursive Collatz Conjecture only till the value is smaller than the original integer

I'm writing an recursion method to calculate collatz conjecture for a sequence of positive integers. However, instead of stopping the calculation when the value reaches 1, I need it to stop when the value become smaller than or equal to the original value. I can't figure out what condition I should put in the if statement.
int collatz (int n) {
printf("%d%s", n, " ");
if(n > collatz(n)) { // here I would get an error saying all path leads to the method itself
return n;
}
else {
if(n % 2 == 0) {
return collatz(n / 2);
}
else {
return collatz((3 * n) + 1);
}
}
}
I used two more parameters:
startValue, to pass through the recursive calls the initial value and
notFirstTime, to check if it is the first call (and not a recursive call). In this case a value n <= startValue is allowed.
Here the code:
int collatz (int startValue, int n, int notFirstTime){
printf("%d%s ", n, " ");
if(n <= startValue && !notFirstTime)
{ // here I would get an error saying all path
//leads to the method itself
return n;
}
else
{
if ( n%2==0 )
{
collatz(startValue, n/2, 0);
}
else
{
collatz(startValue, (3*n)+1, 0);
}
}
}
int main() {
int x = 27;
int firstTime = 1;
int test = collatz(x,x, firstTime);
printf("\nLast value: %d\n", test);
return 0;
}
Please note that I removed two return statements from the recursive calls.

Search of an element on a unsorted array recursively

This is an exercise that I took from an exam. It asks to write a function that receives an unsorted array v[] and a number X and the function will return 1 if X is present in v[] or 0 if X is not present in v[]. The function must be recursive and must work in this manner:
1. Compares X with the element in the middle of v[];
2. The function calls itself (recursion!!) on upper half and on the lower half of v[];
So I've written this function:
int occ(int *p,int dim,int X){
int pivot,a,b;
pivot=(dim)/2;
if(dim==0) //end of array
return 0;
if(*(p+pivot)==X) //verify if the element in the middle is X
return 1;
a=occ(p,pivot,X); //call on lower half
b=occ(p+pivot,dim-pivot,X); //call on upper half
if(a+b>=1) //if X is found return 1 else 0
return 1;
else{
return 0;
}
}
I tried to simulated it on a sheet of paper and it seems to be correct (Even though I'm not sure) then I've written it on ideone and it can't run the program!
Here is the link: https://ideone.com/ZwwpAW
Is my code actually wrong (probably!) or is it a problem related to ideone. Can someone help me? Thank you in advance!!!
The problem is with b=occ(p+pivot,dim-pivot,X); when pivot is 0. i.e. when dim is 1.
the next function call becomes occ(p,1,X); This again leads to the call occ(p,1,X); in a continuous loop.
It can be fixed by adding a condition to the call, as shown in the code below.
int occ(int *p,int dim,int X){
int pivot,a=0,b=0;
pivot=(dim)/2;
if(dim==0){
return 0;
}
if(*(p+pivot)==X)
return 1;
if (pivot != 0)
{
a=occ(p,pivot,X);
b=occ(p+pivot,dim-pivot,X);
}
if(a+b>=1)
return 1;
else{
return 0;
}
}
The implemetation is causing a stack overflow, as the recursion does not terminate if the input contains only one element. This can be fixed as follows.
int occ(int *p, int dim, int X)
{
int pivot, a, b;
pivot = (dim) / 2;
if (dim == 0)
{
return 0;
}
if (*(p + pivot) == X)
{
return 1;
}
if (dim == 1)
{
if (*(p + pivot) == X)
{
return 1;
}
else
{
return 0;
}
}
a = occ(p, pivot, X);
b = occ(p + pivot, dim - pivot, X);
if (a + b >= 1)
{
return 1;
}
else
{
return 0;
}
}
It's enought to change only this one line in the source code to avoid the endless loop with occ(p,1,X):
//if(dim==0) //end of array
if (pivot == 0)
return 0;

Prime no between m and n

I tried a prime no generating question in SPOJ(link : http://www.spoj.com/problems/PRIME1/) .
I'm using seive algorithm . I get the SIGSEGV error when i use spoj gcc . But when i compiled using my ubuntu gcc it works for all the test cases.
Here is my source code . Plz Help
float sqroot( float x)
{
float a , b;
a = x; // copy given value to 'a'
do
{
b = a; // copy value of 'a' to 'b' before 'a' is modify
a = (a + x/a) / 2; // modify 'a' value until we reach sqroot result
}
while( a!= b); // execute loop until a == b
return( a); // 'a ' or 'b' is sqroot of 'x'
}
int main()
{
int prime[4000];
int prime_index=0;
bool find_prime[100001];
int i,j;
int m,n;
int iremainder;
int T,t_index;
int PRIME_FLAG=1;
float square;
int limit;
prime_index++;
prime[prime_index]=2;
for(i=3;i<=32000;i=i+2)
{
PRIME_FLAG=1;
square = sqroot((float)i);
limit = ((int)(square))+1;
for(j=1;j<=prime_index,prime[j]<=limit;j++)
{
if(prime[j]!=0)
{
if((i%prime[j]) == 0)
{
PRIME_FLAG = 0;
break;
}
}
}
if(PRIME_FLAG)
{
prime_index++;
prime[prime_index]=i;
printf("%d\n",i);
}
}
printf("Enter the no of test cases:");
scanf("%d",&T);
if(T<=10)
{
for(t_index=1;t_index<=T;t_index++)
{
printf("Enter the values of m and n :");
scanf("%d%d",&m,&n);
if((m>=1) && (n<=1000000000) && ((n-m)<=100000))
{
if(m == 1)
m=2;
//Set all numbers from m to n as prime
for(i=m;i<=n;i++)
find_prime[i]=true;
//Find the prime numbers between m to n
square = sqroot((float)n);
limit = ((int)(square))+1;
for(i=1;i<=prime_index,prime[i]<=limit;i++)
{
if(m>=prime[i])
{
if(prime[i]!=0)
iremainder=m%prime[i];
j=prime[i]*iremainder;
}
else
{
iremainder=prime[i]-m;
if(m+iremainder == prime[i])
j=2*(m+iremainder);
else
j=m+iremainder;
}
for(;j<=n;j=j+prime[i])
find_prime[j]=false;
}
//Print all prime no's
for(i=m;i<=n;i++)
{
if(find_prime[i])
printf("%d\n",i);
}
}
}
}
return 0;
}
your for loops are wrong.
for(j=1;j<=prime_index,prime[j]<=limit;j++)
should be
for(j=1;(j<=prime_index)&&(prime[j]<=limit);j++)
the first condition will be executed, but the result will be ignored.
So it is luck, that you find a number in the uninitialized array that is larger than limit before you go out of range of the array, which will lead to a SIGSEGV.
for(i=1;i<=prime_index,prime[i]<=limit;i++)
has the same problem.
Click here for more details

Segmentation fault with a recursive function

When I try to execute this:
#include<stdio.h>
int byteland(int a)
{
int e,f,g;
if ((a/2 + a/3 + a/4) < a)
return a;
else
{
e = byteland(a/2);
f = byteland(a/3);
g = byteland(a/4);
return e + f + g;
}
}
int main()
{
int a, b;
scanf("%d", &a);
b = byteland(a);
return 0;
}
I get segmentation fault (core dumped). Any solution?
If you use 0 for a, you get infinite recursion -- stack overflow. You also get infinite recursion for many negative numbers.
Not sure what this function is supposed to do but there is nothing to break the recursion when a is equal to 0.
I would add a clause to break the recursion when a is equal to 0.
int byteland(int a)
{
int e,f,g;
if ( a == 0 )
{
return 0;
}
else if((a/2+a/3+a/4)<a)
{
return a;
}
else
{
e=byteland(a/2);
f=byteland(a/3);
g=byteland(a/4);
return e+f+g;
}
}

Resources