Given an integer, return all sequences of numbers that sum to it

Q:

Given an integer, return all sequences of numbers that sum to it. (Example: 3 -> (1, 2), (2, 1), (1, 1, 1)). 

A: 

 

class CalcSequenceNumber
{
private:
    static void print(int values[], int n)
    {
        for (int i = 0; i < n; ++i) // n may be less then length of values[]
        {
            cout << " " << values[i];
        }
        cout << endl;
    }

    static void decompose(int x, int values[], int index) 
    {
        if(x == 0) 
        {
            print(values, index);
            return ;
        }

        // this algorithm is similar to permutation, charge coin, etc.
        for (int i = 1; i < x; i++) 
        {
            values[index] = i;
            decompose(x - i, values, index + 1);
        }

        // special case for non-zero component
        if (index > 0)  // when i >= x, we need to fill the next number to make (previous numbers + next number == input number)
        {
            values[index] = x;
            decompose(0, values, index + 1);
        }
    }


public:
    static void decompose(int x) 
    {
        cout << "The input number is " << x << " :" << endl;

        int* values = new int[x];
        decompose(x, values, 0);
        delete[] values;
    }
};

samples:

The input number is 3 :
 1 1 1
 1 2
 2 1
The input number is 5 :
 1 1 1 1 1
 1 1 1 2
 1 1 2 1
 1 1 3
 1 2 1 1
 1 2 2
 1 3 1
 1 4
 2 1 1 1
 2 1 2
 2 2 1
 2 3
 3 1 1
 3 2
 4 1

非递归算法:

这个方法是根据上面的输出例了,倒推出来的,但非常适用于这道题目

C/C++

void CalcSequenceNumber(int n)
{
    cout << "The input number is " << n << " :" << endl;

    vector<int> v(n);
    int i = 0;
    while (i < n) v[i++] = 1;

    while (1)
    {
        int j = 0; while (j < v.size()) cout << " " << v[j++]; cout << endl;

        if (v[v.size() - 1] == 1)
        {
            v.pop_back();
            v[v.size() - 1] += 1;
        }
        else
        {
            v[v.size() - 2] += 1;
            int k = v[v.size() - 1] - 1;
            v[v.size() - 1] = 1; k--;
            while (k-- > 0) v.push_back(1);
        }

        if (v[0] == n)
            break;
    }
}

感谢 csdn 网友 (tkminigame), python 代码

def foo3():
    l = [1]*n
    while True:
        print (*l)

        if l[-1] == 1:
            l.pop()
            l[-1] += 1
        else:
            l[-2] += 1
            l[-1:] = [1]*(l[-1] - 1)
        
        if l[0] == n:
            break

  

 

posted @ 2013-01-23 16:24  百分百好牛  阅读(641)  评论(0编辑  收藏  举报