return statement in recursive function - c++

I am trying to write a recursive function for linear search in an array which also returns the first index at which the element is found.
int linearSearch(int *A, int size, int val)
{
if(size>0)
{
if(*A==val)
{
cout<<val<<" is found in the array!";
return i;
}
else
{
linearSearch(A+1,size-1,val);
i++;
}
}
else
{
cout<<val<<" is not there in the array!";
return -1;
}
}
However, when I am trying to catch the valued returned in the main function, value of size is returned instead of -1 in the case when the element is not present in the array. I am not able to figure out why is that happening.

Try this. I added a couple of comments in the code so you can understand it better.
/* i is the initial position. When you are making a call to linearSearch it should be set to 0 */
int linearSearch(int *A, int size, int val, int i)
{
/* When you reach end of the array and havent found value, then return -1 */
/* Every recursive function should have an exit condition */
if(i == size)
return -1;
/* when we found a value return the index */
if (A[i] == val)
return i;
else
/* If not then move to the next value in the array by incrementing index and recurse */
return linearSearch(A, size, val, i + 1);
}

Related

Sub array with a given sum

(The given problem is referred from : https://practice.geeksforgeeks.org/problems/subarray-with-given-sum-1587115621/1?page=1&difficulty[]=0&curated[]=1&sortBy=submissions )
I tried a solution to the above problem but it failed for large values for N and S.
I attempted the following solution to the above problem:
class Solution
{
public:
//Function to find a continuous sub-array which adds up to a given number.
vector<int> subarraySum(int arr[], int n, long long s)
{
// Your code here
long long sum=arr[0];
int first=0,last=0;
vector<int> v{-1,-1};
vector<int> a{-1};
if(arr[0]==s)
{
v[0]=1;
v[1]=1;
return v;
}
for(int i=0;first<n && last<n;i++){
if(sum>s){
if(first==last && (last+1<n)){
sum=sum-arr[first]+arr[first+1];
first++;
last++;
}
else{
if(first==last && last==n-1){
break;
}
if(first<last)
{ sum=sum-arr[first];
first++;
}
} else if(sum<s){
last++;
sum+=arr[last];
}
else if(sum==s){
v[0]=first+1;
v[1]=last+1;
return v;
}
}
return a;
}
};
In the code, 'first' and 'last' are the indexed of the first and the last element of the sub-array.
(Edit: The edited code works!, thanks for all the help!)

Adding int to long

I am creating a recursive formula to add up all the elements in a vector. The problem them I'm having is that my result is not adding to the vector results so it always returns 0. I have tried static_cast to turn it into an int but I'm still not able to figure it out. Here's my code:
long vectorSum(const std::vector<int>& data, unsigned int position) {
int ret = 0;
if(position == data.size()-1) {
return ret;
} else {
ret += data[position];
return vectorSum(data, position+1);
}
}
I am calling the function like this:
std::vector<int> test1;
for(int i = 0; i < 10; i++) {
test1.push_back(i);
}
cout << vectorSum(test1, 0) << "\n";
This is not correct:
ret += data[position];
return vectorSum(data, position+1);
The new value of ret (+= data[position]) isn't being used anywhere or passed back to the caller.
Remeber: ret is strictly local to each invocation of vectorSum(). It doesn't exist outside of your vectorSum(); it's being set to "0" every time you invoke vectorSum().
long vectorSum(const std::vector<int>& data, unsigned int position) {
if(position == data.size())
return 0;
else
return data[position]+vectorSum(data, position+1);
}
Then call it as
int sum=vectorSum(data,0);
Normally, one adds to the value of a recursive call. You are not doing that. In your code, it will keep calling with a modified position until it hits the terminating condition, then that return 0; goes all the way back up to the caller.
long vectorSum(const std::vector<int>& data, unsigned int position) {
int ret = 0;
if(position == data.size()-1) {
return ret;
} else {
ret += data[position]; //this line has no affect on the result!
return vectorSum(data, position+1); //you don't accumulate anything
//this will always return 0
}
}
Instead, you want to add the current value plus the value from the recursive call:
long vectorSum(const std::vector<int>& data, unsigned int position) {
if(position == data.size()-1) {
//terminating condition, return 0
return 0;
} else {
//add current value plus value from processing the rest of the list
return data[position] + vectorSum(data, position+1);
}
}
As a side note: recursion is a great tool, but it can easily be misused by applying it to problems that already have better and more elegant solutions. For this, something like std::accumulate would probably be the most "natural" solution for C++.

How do I return value to main function without directly calling the function

I have multiple functions in my program. Each function has some conditions. If conditions are met, then it passes on the value to another function which again checks the value with some conditions, modifies it.
The first function [named 'squarefree()'] is called from main [obviously] and it further goes on to call another function which in course calls another function untill the process stops at last function named 'end()'. Like this:
#include <iostream>
using namespace std;
int squarefree(int n);
int goodnumber(int sf);
int end(int gn);
int main() {
// your code goes here
int l,r;
cin>>l;
cin>>r;
for(int p=l;p<=r;p++)
{squarefree(p);}
/*int ret=end(int gn); PROBLEM LIES HERE
cout<<ret; */
return 0;
}
int squarefree(int n){
int i;
for(int i=2;i<n;i++)
{
if((n%(i*i))==0)
{
cout<<"number not square free"<<endl;
break;
}
else{
cout<<"number square free"<<endl;
goodnumber(n);
break;
}
}
return 0;
}
int goodnumber(int sf){
cout<<"Sf is:"<<sf<<endl;
int s=0,c=0,flag=0;
for(int j=1;j<=sf;j++)
{
if(sf%j==0)
{
s+=j;
for(int k=2;k<=j/2;++k)
{
if(j%k==0)
{
c++;
}
}
}
}
cout<<"s is:"<<s<<endl;
cout<<"no.of prime numbers dividin s are:"<<c<<endl;
for(int l=2;l<=c/2;++l)
{
if(c%l==0)
{
flag=1;
break;
}
}
if (flag==0)
{cout << "C is a prime number, so this is good number and needs to be passed to next function"<<endl;
end(s);
}
else
{cout << "C is not a prime number"<<endl;
}
return 0;
}
int end(int gn)
{
int sum=0;
sum+=gn;
cout<<"SUm of factors of the good number is:"<<sum<<endl;
return sum;
}
The 'end()' function returns a value sum. Now I want this value sum to be updated everytime the for loop in main() function runs. For example: Sum in first iterations is 5, sum is 2nd iteration is 10, so total sum gets 15 and so on.
If somehow, the value returned by end function can be fetched into main function, that would be great.
Look at all those int-returning functions that are always returning 0. You might be able to take advantage of that.
A trivial example:
#include <iostream>
int step3(int val)
{
return val * val;
}
int step2(int val)
{
return step3(val + 1);
}
int step1(int val)
{
return step2(val * 2);
}
int main()
{
std::cout << step1(1);
}
But take care. You might find a case where you don't get any valid results and need to inform the caller that no result was found.
In addition to the idea of having the functions return the result of the next stage in the pipeline, which is an excellent idea, you can pass the address of the variable in which to store the result (allowing you to return more than one result, or an error code), or store the result of each stage in a temporary variable and return that (allowing you to use a result in more than one computation). I would advise against using a global variable to bypass the stack; it’s considered poor practice.
Some Examples:
// Returning the result of the next stage in the pipeline:
int g(int);
int f(int x)
{
return g(x);
}
// Passing a variable by reference:
enum errcode { success, failure };
errcode sqr( int input, int& output )
{
output = input * input; // This modifies the second variable the caller gave.
return success;
}
// Storing in a temporary variable:
int stage2(int);
int stage1(int x)
{
const int y = stage2(x); // Store the result in a temporary.
const int z = sqr(y);
return z;
}
// Passing results through a global variable is a bad idea:
int necessary_evil = 0; // Declared in global scope; should at least be
// declared static if possible to make it visible only in this source file.
// Namespaces are a fancier way to do something similar.
void kludge(int x)
{
necessary_evil = x * x; // The caller will check the global.
return;
}
There are examples of all of these in the standard library: printf() is essentially a wrapper for vfprintf(), strtol() takes a parameter by reference that the function sets to a pointer to the remainder of the string, and errno is a global variable.

replace all negative value from array using recursion C

I want replace all negative value by zero(recursively). And I have use C and recursion. It's was my homework.
Desired output:
0 4 0 3
What I get:
0 4 -9 3
My code:
#include <stdio.h>
int zeros_value(int n, int tab[])
{
if (n==0) return 0;
if(tab[n-1] < 0){
tab[n-1]=0;
}
else{
return zero_value(n-1,tab);
}
}
int main(void)
{
int tab[4] = {0,4,-9,3};
int number = 0;
int i;
zero_value(4, tab);
for(i=0;i<4;i++)
printf("%d ", tab[i]);
return 0;
}
When you hit the first negative, the recursion doesn't continue anymore and the function returns. You don't really need to return any value from the function. You can rewrite it to make a void function.
#include <stdio.h>
void zero_value(int n, int tab[])
{
if (n==0) return;
if(tab[n-1] < 0) tab[n-1]=0;
zero_value(n-1,tab);
}
int main(void)
{
int tab[4] = {0,4,-9,3};
int number = 0;
int i;
zero_value(4, tab);
for(i=0;i<4;i++)
printf("%d ", tab[i]);
return 0;
}
I see the following problems with your code.
The function zero_values does not have a valid return statement when tab[n-1] is negative. You can see it more clearly if you change the function to:
int zeros_value(int n, int tab[])
{
if (n==0)
{
return 0;
}
if(tab[n-1] < 0)
{
tab[n-1]=0;
// No return here.
}
else
{
return zero_value(n-1,tab);
}
// No return here either.
}
Calling such functions leads undefined behavior.
The printf line in main is not right.
printf("%d%d%d%d", zeros_value(4,tab));
That line needs four arguments of type int after the format string to work correctly. Not providing enough arguments to printf is also cause for undefined behavior.
You can use solution provided in the answer by #usr to solve both problems.
If you have any valid reasons to return an int from zero_value, you need to change the implementation appropriately. It's not clear from your post what that return value is supposed to be.

Searching a string inside a char array using Divide and Conquer

Let's say that I have a struct array and each element has a name. Like:
struct something{
char name[200];
}a[NMAX];
Given a new string (char array), i need to find the correct index for it using divide and conquer. Like:
char choice[200];
cin>>chioce;
int k=myFunction(choice); // will return the index, 0 otherwise
// of course, could be more parameters
if( k )
cout<<k;
I don't know how to create that searching function (I tried, I know how D&C works but i'm still learning! ).
And no, i don't want to use strings !
This is what i tried:
int myFunction(char *choice, int l,int r) // starting with l==0 && r==n-1
{
int m;
if(strcmp(a[m].name,choice)==0)
return m;
else{
m=(l+r)/2;
return myFunction(choice,l,m-1);
return myFunction(choice,m+1,r);
}
}
This is my solution for your above problem. But i have modified a few things in your code.
#include<iostream>
using namespace std;
#define NMAX 10
struct something{
char *name; //replaced with char pointer so that i can save values the way i have done
}a[NMAX];
int myFunction(char *choice, int l,int r) // starting with l==0 && r==NMAX-1
{
if(l>r) //return if l has become greater than r
return -1;
int m=(l+r)/2;
if(strcmp(a[m].name,choice)==0)
return m+1;
else if(l==r) //returned -1 as the value has not matched and further recursion is of no use
return -1;
else{
int left= myFunction(choice,l,m-1);//replaced return
int right= myFunction(choice,m+1,r);//by saving values returned
if(left!=-1) //so that i can check them,
return left; //otherwise returning from here onlywould never allow second satatement to execute
if(right!=-1)
return right;
else
return -1;
}
}
int main(){
a[0].name="abc";
a[1].name="a";
a[2].name="abcd";
a[3].name="abcf";
a[4].name="abcg";
a[5].name="abch";
a[6].name="abcj";
a[7].name="abck";
a[8].name="abcl";
a[9].name="abcr";
char choice[200];
cin>>choice;
int k=myFunction(choice,0,NMAX-1); // will return the index, 0 otherwise
// of course, could be more parameters
if( k !=-1)
cout<<k;
else
cout<<"Not found";
return 0;
}
Hope it will help.