Search of an element on a unsorted array recursively - c

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;

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).

Subset using Backtracking

The following question I was asked to solve using backtracking:
It's supposed to return the length of the longest subset of differences that replaces a sign.
For example:
for this given series [11,6,7,8,9] it returns 3.
because it includes this subset [11,8,9] and [11,6,8] .
*In this series a:[11,8,9] a[1]-a[0]<0 and a[2]-a[1]>0 .In other words the sign of the difference between each neighbor changes. *
I pretty much finished the coding but have no idea how to return the max length using backtracking.
Any note/help will be highly appreciated.
/* this function checks if we can add another number to the sequence
and still the differences between the numbers replace a sign.It's enough
to check the last two*/
int check_rec(int series[],int arr[],int n)
{ int count=0,c=n;
int temp1=0,temp2=0;
while(c>=0 && count!=2)
{
if (arr[c]==1 && count==0)
{ temp1=series[c];
count++;
}
if (arr[c]==1 && count==1 )
{ temp1=series[c];
count++;
}
c--;
}
if(count<2) return 1;
if(temp1>temp2 && series[n+1] < temp1) return 1;
if(temp1<temp2 && series[n+1]> temp1) return 1;
return 0;
}
int count_ones(int arr[],int n)
{ int c;
for(int i=0;i<n;i++)
{
if(arr[i])
c++;
}
return c;
}
// 1 in the array helper indicates that the index has been chosen.
void max_crazy(int series[], int n,int helper[],int length,int max[])
{
if(n==0)
{
int x=count_ones(helper,n);
if(x>max[0])
max[0]=x;
}
for(int i=0;i<2;i++)
{
if(n!=length && i==1 && !check_rec(series,helper,length-n))
continue;
helper[0]=i;
max_crazy(series,n-1,helper+1,length,max);
}
}
you can send a pointer that saves the max in the recursive function , and every time you reach the if(n==0) you have to check if the count_ones bigger than max then max=count_ones

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.

Programs works when compiled in clang, but not gcc in Windows

Have this search function that works when I compile in Linux using clang, but on Windows using MinGW gcc, I do not get the right answer. Included in the code is an array where clearly the value I'm looking for is in the array. So output should be "Found it!". Anyone know what might the issue be with windows?
#include <stdio.h>
#include <stdbool.h>
bool re_search(int value, int values[], int first, int last);
int main(void)
{
int value = 12;
int values[] = {2,4,5,12,23,34};
int n = 6;
if (re_search(value, values, 0, n-1))
{
printf("Found it!\n");
}
else
{
printf("Did not find it\n");
}
return 0;
}
bool re_search(int value, int values[], int first, int last)
{
last = last-1;
int middle = (first+last)/2;
while (first <= last)
{
if (value == values[middle])
{
return true;
}
else if (value > values[middle])
{
first = middle + 1;
middle = (first + last) / 2;
return re_search(value, &values[middle], first, last);
}
else
{
last = middle - 1;
middle = (first + last) / 2;
return re_search(value, &values[first], first, last);
}
}
return false;
}
Your recursive call return re_search(value, &values[middle], first, last); is passing in both an array which starts at the midpoint, and a new value of first which counts from the whole array's start. You want to do one or the other; not both.
That is, you first call with:
values == {2,4,5,12,23,34}
first == 0
last == 5
In the first iteration, you try middle == 2, so values[middle] is 5, which is less than 12. You then recurse with
values == {12,23,34}
first == 3
last == 5
And - oh dear! - even values[first] is now out of range. Chances are, on Linux you got (un)lucky and hit the value you were searching for past the end of the array.
does not matter whether GCC and windows.
bool re_search(int value, int values[], int first, int last){
if (first <= last){
int middle = (first+last)/2;
if (value == values[middle]){
return true;
} else if (value > values[middle]){
return re_search(value, values, middle + 1, last);
} else {
return re_search(value, values, first, middle - 1);
}
}
return false;
}
bool re_search(int value, int values[], int first, int last){
while (first <= last){
int middle = (first+last)/2;
if (value == values[middle]){
return true;
} else if (value > values[middle]){
first = middle + 1;
} else {
last = middle - 1;
}
}
return false;
}

C- Fix Stack overflow in Recursion

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;
}

Resources