在Matlab中计算[a1 a2 a3 ... an]的所有两个元素和

时间:2012-10-26 13:17:45

标签: matlab for-loop vector sum

上下文:我正在使用Matlab开发Project Euler Problem 23,以便练习我几乎不存在的编程技巧。

我的问题:

现在我有一个大约有6500个数字(范围从12到28122)的向量作为元素,并且想要计算所有两个元素的总和。那就是我只需要每个和的一个实例,所以计算a1 + a就没有必要计算+ a1。

编辑以澄清:这包括总和a1 + a1,a2 + a2,...,an + an。

问题是这太慢了。

问题特定限制:

这是一个给定的28123或以上的数字不需要计算,因为那些不能用于进一步解决问题。

我的方法:

AbundentNumberSumsRaw=[];
for i=1:3490
    AbundentNumberSumsRaw=[AbundentNumberSumRaw AbundentNumbers(i)+AbundentNumbers(i:end);
end

这非常有效:p

我的评论:

我很确定逐渐增加向量AbundentNumbersRaw是错误的编码,因为这意味着内存使用量会不必要地增加。我还没有这样做,因为a)我不知道预先分配的大小向量和b)我无法想出一种方法,以有序的方式将总和注入AbundentNumbersRaw而不使用一些丑陋的嵌套环路。

“for i = 1:3490”低于元素数量只是因为我检查并发现索引高于3490的数字的所有结果总和对我来说太大了无法使用。

我很确定我的主要问题是该程序需要对向量AbundentNumbersRaw进行大量增量增量。

非常感谢任何和所有帮助和建议:)

干杯

拉​​斯穆斯

3 个答案:

答案 0 :(得分:3)

假设

a = 28110*rand(6500,1)+12;

然后

sums = [
 a(1) + a(1:end)
 a(2) + a(2:end)
 ... 
];

是你想要的计算。

您还声明应丢弃其值超过28123的总和。

这可以概括为:

% Compute all 2-element sums without repetitions
C = arrayfun(@(x) a(x)+a(x:end), 1:numel(a), 'uniformoutput', false);
C = cat(1, C{:});

% discard sums exceeding threshold
C(C>28123) = [];

或使用循环

% Compute all 2-element sums without repetitions
E = cell(numel(a),1);
for ii = 1:numel(a)
    E{ii} = a(ii)+a(ii:end); end
E = cat(1, E{:});

% discard sums exceeding threshold
E(E>28123) = [];

简单测试表明arrayfun比循环快一些,所以我选择arrayfun选项。

答案 1 :(得分:0)

由于你的主要问题是要找出,给定集合中的哪些整数可以写成不同集合中两个整数的总和,我会选择不同的方法:

AbundantNumbers = 1:6500; % replace with the list you generated somewhere else
maxInteger = 28122;
AbundantNumberSum(1:maxInteger) = true; % logical array

for i = 1:length(AbundantNumbers)
  sumIndices = AbundantNumbers(i) + AbundantNumbers;
  AbundantNumberSum(sumIndices(sumIndices <= maxInteger)) = false;
end

不幸的是,这不是你的问题的答案,而是你的问题;-)对于MatLab解决你原来问题的方法,请看Rody Oldenhuis的优雅答案。

答案 2 :(得分:0)

我的方法如下:

v = 1:3490;   % your vector here
s = length(v);
result = zeros(s);  % preallocate memory

for m = 1:s
     result(m,m:end) = v(m)+v(m:end);    
end

你将获得一个3490 x 3490元素的矩阵,其中一半以上是0。