如果我有一个二进制向量x
:
x = [1 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 1 0];
和位置(线性索引)p
:
p = 7;
我想找到矢量x
中第一个非零值的位置,从位置p
开始并向正方向移动:
x = [1 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 1 0];
↑ ↑
%starting position (7) %position to find (24)
可以通过for循环来完成:
for ii = p:length(x)
if x(ii)~=0
ind = ii
break
end
end
但是有没有更聪明/更有效的方法来达到相同的结果?
答案 0 :(得分:3)
您可以从p中选择数组并使用find。
x = [1 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 1 0];
p = 7 ;
iwant = find(x(p:end)>0,1)
答案 1 :(得分:3)
快速计时测试:
method1
是OP中的循环。
method2
是this answer的固定版本,使用find
并复制数组。
(我没有添加bwconncomp
答案,因为它的速度明显慢了。)
当然,测试结果取决于找到非零元素之前要访问的元素的预期数量以及数组长度n
。 q
是第一个非零元素的位置。我总是拿p=10
。时间(以秒为单位):
n q method1 method2
------ ------ ---------- ----------
1e3 p+5 5.9714e-07 2.8644e-06
1e3 end-5 3.9806e-06 3.3714e-06
1e6 p+5 6.4526e-07 0.0027
1e6 end-5 0.0029 0.0033
因此,find
方法的运行时间取决于复制数组和调用find
的开销,而循环方法的时间取决于一个人需要访问多少数组元素才能找到第一个非零元素。
测试代码:
N = 1e6;
p = 10;
x = zeros(1,N);
%x(p+5) = 1;
x(end-5) = 1;
timeit(@()method1(x,p))
timeit(@()method2(x,p))
function ind = method1(x,p)
for ii = p:length(x)
if x(ii)~=0
ind = ii;
break
end
end
end
function ind = method2(x,p)
ind = find(x(p:end),1) + p-1;
end
答案 2 :(得分:2)
您还可以使用 bwconncomp()函数。该函数将为您提供给定数组中的那些位置。职位信息将保存在 islands.PixelIdxList 中。因此,要查找的位置(当然是在p之后)是 ptf 数组的第一个元素:
islands=bwconncomp(x);
positions=[cell2mat(islands.PixelIdxList(:))];
ptf=positions(positions(:)>p);