Search code examples
c++algorithmstl-algorithm

How to find all matching numbers, that sums to 'N' in a given array


My goal here is to find all possible combinations that sums to a given total. For example, if the array is 2 59 3 43 5 9 8 62 10 4 and if the total is 12, then possible combinations are

2 10
3 9
8 4
5 3 4

Here is the first set of code, that I've written. Wondering the best improvements that can be done on this.

   int find_numbers_matching_sum(int *number_coll, int total)
{

    int *search_till = lower_bound(number_coll,number_coll+TOTAL_SIZE, total);
    int location = search_till - number_coll;
    if (*search_till > total && location > 0 )
    {
        --location;
    }

    while ( location >= 0 )
    {
        find_totals(number_coll,total,location);
        --location;
    }
    return 1;
}

int find_totals(int *number_coll, int total, int end_location)
{
    int left_ones = total - number_coll[end_location];
    int curloc = end_location;
    int *search_till = 0;
    int location ;
    int all_numbers[10];
    int i = 0;

    all_numbers[i] = number_coll[end_location];
    while ( left_ones && curloc >= 0 )
    {
        search_till = lower_bound(number_coll,number_coll+end_location, left_ones);
        location = search_till - number_coll;
        if (*search_till > left_ones && location > 0 )
        {
            --location;
        }
        else if ( left_ones < *search_till )
        {
            break;
        }
        curloc=location;
        left_ones = left_ones - number_coll[curloc];
        all_numbers[++i] = number_coll[curloc];
        end_location = curloc - 1;
    }

    if ( !left_ones )
    {
        while ( i>=0)
        {
            cout << all_numbers[i--] << ' ';
        }
    }
    cout << endl;
    return 1;


}

Solution

  • #include <iostream>
    #include <vector>
    
    using namespace std;
    
    struct State {
        int v;
        const State *rest;
        void dump() const {
            if(rest) {
                cout << ' ' << v;
                rest->dump();
            } else {
                cout << endl;
            }
        }
        State() : v(0), rest(0) {}
        State(int _v, const State &_rest) : v(_v), rest(&_rest) {}
    };
    
    void ss(int *ip, int *end, int target, const State &state) {
        if(target < 0) return; // assuming we don't allow any negatives
        if(ip==end && target==0) {
            state.dump();
            return;
        }
        if(ip==end)
            return;
        { // without the first one
            ss(ip+1, end, target, state);
        }
        { // with the first one
            int first = *ip;
            ss(ip+1, end, target-first, State(first, state));
        }
    }
    
    int main() {
        int a[] = { 2,59,3,43,5,9,8,62,10,4 };
        int * start = &a[0];
        int * end = start + sizeof(a) / sizeof(a[0]);
        ss(start, end, 12, State());
    }