How to find strings of ones in a vector

8 次查看(过去 30 天)
I have... [3 1 1 5 7 2 1 1 1 9 10]; and I would like to find the indices for my "runs" of ones. I would like my output to be: [2 3 7 9]. (The start and end of the runs of ones).

回答(4 个)

Jan
Jan 2011-8-27
Another solution:
x = [3 1 1 5 7 2 1 1 1 9 10];
isOne = [false, (x==1), false];
index = [strfind(isOne, [false, true]); ...
strfind(isOne, [true, false]) - 1];
index = reshape(index, 1, []);
This takes about the half time of Oleg's method - if x has 10'000 elements.
  3 个评论
Fangjun Jiang
Fangjun Jiang 2011-8-28
Jan, I found one solution without using strfind(). It's a little faster.
Andrei Bobrov
Andrei Bobrov 2011-8-28
+1. Hi Jan! This is my favorite method, Matt Fig - first use for such tasks.

请先登录,再进行评论。


Fangjun Jiang
Fangjun Jiang 2011-8-28
Can use find() directly. And it's faster than strfind().
x=[3 1 1 5 7 2 1 1 1 9 10];
a=diff([0 x 0]==1);
b=[find(a==1);find(a==-1)-1];
c=b(:)'
  2 个评论
Fangjun Jiang
Fangjun Jiang 2011-8-28
Speed test results:
%%
x=rand(1,1000);y=x>0.5;
x(y)=1; x(~y)=0;
t1=0;t2=0;
for k=1:1000;
%Jan's method
tic;
isOne = [false, (x==1), false];
index = [strfind(isOne, [false, true]); ...
strfind(isOne, [true, false]) - 1];
index = reshape(index, 1, []);
t1=t1+toc;
%Fangjun's method
tic;
a=diff([0 x 0]==1);
b=[find(a==1);find(a==-1)-1];
c=b(:)';
t2=t2+toc;
end
fprintf('Jan''s time: %f\n',t1);
fprintf('Fangjun''s time: %f\n',t2);
Jan's time: 0.082744
Fangjun's time: 0.080910

请先登录,再进行评论。


the cyclist
the cyclist 2011-8-27
There are probably less pedantic ways, but I think this does what you want.
x = [3 1 1 5 7 2 1 1 1 9 10];
isOne = (x==1);
isSameAsPrev = diff([NaN x])==0;
isSameAsNext = diff([x NaN])==0;
indexToFirstOrLastOne = find(isOne & (not(isSameAsPrev) | not(isSameAsNext)))
  1 个评论
Fangjun Jiang
Fangjun Jiang 2011-8-28
Need to improve to handle single 1 case. For example, if x=[1 2 1 1 1]; result should be [1 1 3 5]. Otherwise, if result is [1 3 5], won't be able to tell if x=[1 1 1 2 1]

请先登录,再进行评论。


the cyclist
the cyclist 2011-8-28
Slightly more efficient version of my other answer:
isOne = (x==1);
isSameAsPrevOrNext = diff([NaN x NaN])==0;
isFirstOrLastOne = find(isOne & not(isSameAsPrevOrNext(1:end-1) & isSameAsPrevOrNext(2:end)));

类别

Help CenterFile Exchange 中查找有关 Matrix Indexing 的更多信息

标签

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by