How to find strings of ones in a vector

6 visualizaciones (últimos 30 días)
Maddie
Maddie el 27 de Ag. de 2011
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).

Respuestas (4)

Jan
Jan el 27 de Ag. de 2011
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 comentarios
Fangjun Jiang
Fangjun Jiang el 28 de Ag. de 2011
Jan, I found one solution without using strfind(). It's a little faster.
Andrei Bobrov
Andrei Bobrov el 28 de Ag. de 2011
+1. Hi Jan! This is my favorite method, Matt Fig - first use for such tasks.

Iniciar sesión para comentar.


Fangjun Jiang
Fangjun Jiang el 28 de Ag. de 2011
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 comentarios
Fangjun Jiang
Fangjun Jiang el 28 de Ag. de 2011
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
Andrei Bobrov
Andrei Bobrov el 28 de Ag. de 2011
+1

Iniciar sesión para comentar.


the cyclist
the cyclist el 27 de Ag. de 2011
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 comentario
Fangjun Jiang
Fangjun Jiang el 28 de Ag. de 2011
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]

Iniciar sesión para comentar.


the cyclist
the cyclist el 28 de Ag. de 2011
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)));

Categorías

Más información sobre Matrix Indexing en Help Center y File Exchange.

Etiquetas

Community Treasure Hunt

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

Start Hunting!

Translated by