class Solution { public: void f(vector <int> arr, int N, int i , int sum, vector <int> g){ if (i>= N){// when index reaches the end of the array g.push_back(sum);//add the final sum to vector g return; }else{ sum= sum+arr[i]; //include this element in the sum f(arr,N, i+1,sum,g); sum = sum-arr[i];//do not include this element in the sum f(arr, N, i+1,sum,g); } } vector<int> subsetSums(vector<int> arr, int N) { vector <int> g; int sum=0; int i=0; f(arr, N,i,sum,g); return g; }//main block will print g in sorted order };
THis is my code written in cpp to return the sum of all subsequences as an vector. this is a basic recursion problem . the vector g stores the final sums. But g found to be empty.
input: {2,3} , 2
expected : 0 2 3 5

- 11
- 1
-
The argument `g` of the method `f()` is local variable of `f()`. – fana Feb 24 '23 at 06:22
-
What have you found out during debugging? – MrSmith42 Feb 24 '23 at 07:26
-
@gowtham_wick -- I added some more advice related to reference too and how using it with const can save you some copies. – Shaun Ramsey Feb 26 '23 at 03:13
2 Answers
As Shaun mentioned, you are passing the vector g by value in your function f. When you insert the sum to vector g, you are doing so on a local object. Hence the vector g in subsetSums()
is empty. (Try printing useful information when debugging your own code.)
You can read up on pass-by-reference vs pass-by-copy/value: https://www.ibm.com/docs/en/zos/2.4.0?topic=functions-function-calls
A simple change will have your desired output
void f(vector <int> arr, int N, int i , int sum, vector <int>& g)

- 21
- 4
-
What does this answer really add to the "other answer" that you've mentioned? – Adrian Mole Feb 28 '23 at 15:13
-
@AdrianMole the "other answer" was brief at the time I wrote this answer, it has been edited thereafter. – taneres Feb 28 '23 at 16:24
-
OK, thanks for clarifying that. And sorry for any misunderstanding. :-) – Adrian Mole Feb 28 '23 at 16:25
Arguments in C++ are call by value by default. So you're passing a copy of an empty vector g and filling it up locally in the function. You could alter g to be pass by reference by inserting an ampersand, &, before the g in the function definition (not the function call).
void f(vector <int> arr, int N, int i, int sum, vector<int>&g){
You can see the ampersand in the call there. You don't need to alter your function call at all. With call by reference, you're saying that the g passed in the function call is "the same" g as the one in the function f. In this case, when you fill that g in the function, it is also filling the one in the function call.
Before this edit though, instead of being "the same" g it was simply a copy. In call by value, the parameters passed in are copied as values. So when the function edits those variables, they are seen only locally by the function itself.
Lastly, it is often advantageous to always send vectors as call by reference to avoid copying large amounts of data. In this case, if you know the function will not change the vector, then put a const in front of the vector. So if f will not modify arr, you could make it a call by 'constant' reference.
void f(const vector<int> &arr, int N, int i, int sum, vector<int> &g){

- 562
- 4
- 14