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