给出一个数字' c'和一个数字列表'我试图生成我可以拥有的所有c和数字中的任何子集。 例如。 (1,[2,4,8]),我应该生成(注意我们应该总是有一个c) [1,3,5,9,7,11,13,15]
我写了下面的代码,但并不是所有的总和都出现了。有什么问题?
function result = allsums(c, numbers)
if isempty(numbers)
result = [];
else
[nr n_numbers] = size(numbers);
for i = 1:n_numbers
result = cat(2, c+numbers(i), allsums(c, cat(2,numbers(1:i-1),numbers(i+1:end))));
end
end
result = cat(2, result, c+sum(numbers,2));
end
答案 0 :(得分:3)
这可能是一种方法 -
%// Input array and scalar
numbers = [2,4,8]
c = 1;
%// Generate all sums for all combinations with nchoosek; then add up with c
combsums = arrayfun(@(n) sum(nchoosek(numbers,n),2),1:numel(numbers),'Uni',0)
result = [c ; c+vertcat(combsums{:})]
代码运行 -
result =
1
3
5
9
7
11
13
15
答案 1 :(得分:2)
错误的是:
result = cat(2, sums, c+sum(numbers,2));
因为你在没有输入参数的情况下调用了函数sums
,而你用2个输入参数编写了函数。
更新:
如果length(numbers)
小于15(http://www.mathworks.com/help/matlab/ref/nchoosek.html),您可以尝试这样nchoosek
:
function result = sums(c, numbers)
result = [];
if ~isempty(numbers)
[nr n_numbers] = size(numbers);
result = c;
for i = 1:n_numbers
combi = nchoosek(numbers, i);
for j = 1:size(combi, 1)
result(end+1) = c + sum(combi(j,:));
end
end
end
result = unique(result);
end
p / s:只是一个非常快速的例子,你可以尝试优化代码,我不确定使用像你这样的递归更好还是使用Matlab的内置函数更好......
答案 2 :(得分:2)
单线解决方案怎么样?
c = 1; %// number
S = [2 4 8]; %// set
result = unique(c+S*(dec2bin(0:2^numel(S)-1).'-'0'));
解释:此处的密钥为dec2bin(0:2^numel(S)-1).'-'0'
,它会生成0
- 1
模式,指示集合S
中的哪些元素已添加。在示例中,这是
0 0 0 0 1 1 1 1
0 0 1 1 0 0 1 1
0 1 0 1 0 1 0 1
每列对应S
的不同子集。矩阵乘以S
然后给出每个子集的总和。