假设我有一个数组
a[3]={1,3,8}
我希望输出是一个数组,其中包含通过添加数组a中的数字以及数组a的元素获得的数字。即,
b[0]=1
b[1]=3
b[2]=8
b[3]=4 //(1+3)
b[4]=9 //(1+8)
b[5]=11 //(3+8)
b[6]=12 //(1+3+8)
我该怎么做?
答案 0 :(得分:3)
因此,您希望生成一组数字的所有可能子集并列出它们的总和。
首先,您要枚举所有子集。由于包含2 ^ N
元素的集合中有N
个子集,因此您可以通过迭代从0到1 << (sizeof(arr) / sizeof(arr[0]))
的自然数并在下面处理数字的二进制表示来执行此操作。方式:如果某个特定位设置在位置k
,则k
元素位于当前生成的子集中,否则不是。
然后,您应该将所有选定元素添加到一起并将结果存储在另一个数组的下一个插槽中(显然是2 ^ N
)。
#define COUNT(a) (sizeof(a) / sizeof(a[0]))
#include <limits.h> // for CHAR_BIT
unsigned a[3] = { 1, 3, 8 };
unsigned sums[1 << COUNT(a)] = { 0 };
for (unsigned i = 0; i < COUNT(sums); i++) {
for (unsigned j = 0; j < sizeof(i) * CHAR_BIT; j++) {
if ((i >> j) & 1) {
sums[i] += a[j];
}
}
}
for (unsigned i = 0; i < COUNT(sums); i++) {
printf("%d\n", sums[i]);
}
答案 1 :(得分:0)
我会这样做:
b[0] = 0; //This is not listed in the question, but should be included in the result IMHO.
for(long i = 0; i < elementsA; i++) {
long preexistingElements = 1 << i;
long curElement = a[i];
for(long j = 0; j < preexistingElements; j++) {
b[j + preexistingElements] = b[j] + curElement;
}
}
该算法在结果数组的大小上是线性的,因为每个元素都是以不变的成本计算的。
如果你真的必须排除零并想要malloc结果数组,则转动算法,使b从后面填充,零元素作为最后一个元素。