gcd(A1,A2,…)计算元素A1(1),A2(1)的GCD,….作为存储在向量A中的元素,如何计算gcd(A)?
(我的意思是,gcd(4,2,8)= 2,gcd([4,2,8]会在GNU Octave 4.0.0中引发错误). 最佳答案 随着单元阵列的扩展
这是一个单行,仅在八度音程中有效(感谢nirvana-msu指出matlab的限制):
A = [10 25 15];
gcd(num2cell(A){:})
# ans = 5
这使用单元阵列扩展,这有点隐藏there:
Accessing multiple elements of a cell array with the ‘{’ and ‘}’
operators will result in a 07001 of all the requested
elements
所以这里A {:}被解释为A(1),A(2),A(3),因而gcd(A {:})被解释为gcd(A(1),A(2),A(3) )
性能
仍在八度音阶
A = 3:259;
tic; gcd(num2cell(A){:}); toc
Elapsed time is 0.000228882 seconds.
与@nirvana_msu中的gcd_vect回答,
tic; gcd_vect(A); toc
Elapsed time is 0.0184669 seconds.
这是因为使用递归意味着高性能损失(至少在八度音阶下).实际上,对于A中超过256个元素,递归限制已用尽.
tic; gcd_vect(1:257); toc
<... snipped bunch of errors as ...>
error: evaluating argument list element number 2
error: called from
gcd_vect at line 8 column 13
使用Divide and conquer algorithm可以大大改善这一点
虽然单元阵列扩展(仅限八度)可以很好地扩展:
A = 127:100000;
tic; gcd(num2cell(A){:}); toc
Elapsed time is 0.0537438 seconds.
划分和征服算法(最好)
这个应该在matlab下工作(虽然没有经过测试.欢迎反馈).
它也使用递归,就像在其他答案中一样,但是使用Divide and conquer
function g = gcd_array(A)
N = numel(A);
if (mod(N, 2) == 0)
% even number of elements
% separate in two parts of equal length
idx_cut = N / 2;
part1 = A(1:idx_cut);
part2 = A(idx_cut+1:end);
% use standard gcd to compute gcd of pairs
g = gcd(part1(:), part2(:));
if ~ isscalar(g)
% the result was an array, compute its gcd
g = gcd_array(g);
endif
else
% odd number of elements
% separate in one scalar and an array with even number of elements
g = gcd(A(1), gcd_array(A(2:end)));
endif
endfunction
定时:
A = 127:100000;
tic; gcd_array(A); toc
Elapsed time is 0.0184278 seconds.
所以这似乎比单元阵列扩展更好.