Search code examples
c++subset-sum

How does this recursive function "end" rather than loop indefinitely (or throw an error)?


I came across this subset_sum coding problem/solution and am trying to understand in depth how it works.

To quickly summarize the problem: given an array of length n, find the largest number in the array and then find if there is any combination of numbers inside that array that, when summed, equal the largest number.

The setup of this problem is simple enough, but the actual function of the recursive function that checks all of the array combinations is where I'm a little confused. I've been reading about recursive functions and understand it conceptually, however, I'm having difficult following the exact flow of this particular program and am hoping someone could provide some assistance here.

string flag = "false";

void checkSubsets(int *arr, int i, int length, int *subset, int j, int max) { 
  if (i == length) {
    int index = 0;
    int setSum = 0;
    while (index<j) {
      setSum = setSum + subset[index]; 
      ++index;
      if (setSum == max) { 
        flag = "true";
      }
    }
    return;
  }

  checkSubsets(arr,i+1,length,subset,j, max);
  subset[j] = arr[i]; 
  checkSubsets(arr,i+1,length,subset,j+1, max);
}

string ArrayAddition(int arr[], int arrLength) {
  int subset[100]; 
  int max = arr[0]; 
  int maxIndex = 0; 

  for (int i = 0; i<arrLength;i++) { 
    if (arr[i] > max) {
      max = arr[i];
      maxIndex = i; 
    }
  }

  for (int j = maxIndex; j<arrLength-1;j++) { 
    arr[j] = arr[j+1];
  }

  arr[arrLength-1] = 0; 

  checkSubsets(arr, 0, arrLength, subset, 0, max); 

  return flag; 
}

Solution

  • The recursion ends when i reaches length:

    void checkSubsets(int *arr, int i, int length, int *subset, int j, int max) { 
      if (i == length) {
        // stuff 
        return; // ends here.
      }
    
      // else recurse:
      checkSubsets(arr,i+1,length,subset,j, max);   // i+1
      subset[j] = arr[i]; 
      checkSubsets(arr,i+1,length,subset,j+1, max); // i+1
    }
    

    For each call, you call it with i+1 and when i == length, it does not recurse deeper but does instead return.