如何识别从第1个元素开始的向量中至少10个相邻"1"的第一次出现,第1个元素仅由0和1组成?
A=[0 1 0 0 0 1 1 1 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 1 0 1]
Run Code Online (Sandbox Code Playgroud)
代码应返回A的索引(在此示例中为12),其中1的序列开始.
摘要:循环arrayfun一英里!
这是使用经典旧循环的方法:
function x = test_loop(A)
for ii = 1:numel(A)-9
x = ii*(all(A(ii:ii+9)));
if x
break;
end
end
end
Run Code Online (Sandbox Code Playgroud)
现在,我们来研究arrayfunvs经典for-loops 的性能:
arrayfun方法:
test_array = @(A)find(arrayfun(@(x) all(A(x:x+9)==ones(1,10)), 1:numel(A)-9)==1,1)
A = [0 1 0 0 0 1 1 1 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 1 0 1];
B = repmat(A,1,10); %% 1x300 array
f = @() test_array(A);
g = @() test_loop(A);
Run Code Online (Sandbox Code Playgroud)
您的阵列的基准测试结果(1x30):
timeit(f)
ans =
2.1397e-04
timeit(g)
ans =
2.6224e-05
Run Code Online (Sandbox Code Playgroud)
对于大小为1x300的数组的基准测试结果:
f = @() test_array(B);
g = @() test_loop(B);
timeit(f)
ans =
0.0021
timeit(g)
ans =
2.6598e-05
Run Code Online (Sandbox Code Playgroud)
如果在向量的后期找到第一个序列,则循环会慢一点,但仍然比arrayfun快:
B(1:220) = 0;
f = @() test_array(B);
g = @() test_loop(B);
timeit(f)
ans =
0.0021
timeit(g)
ans =
4.5033e-04
Run Code Online (Sandbox Code Playgroud)
编辑:
为什么每次迭代都会将计数器递增1?以下循环大约是for循环的两倍,具体取决于序列在向量中出现的位置以及零之间的间距.
它仍然较慢conv,但认为它值得分享:
function x = test_loop(A)
ii = 1;
x = false;
while ~x
k = find(A(ii:ii+9)~=1, 1, 'last');
x = isempty(k)*ii;
ii = ii + k;
end
end
Run Code Online (Sandbox Code Playgroud)