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