How to find a chunk of a certain number of zeros inside a vector
Mostrar comentarios más antiguos
Hi all,
I have a vector of ones and zeros randomly distributed.
i.e: A = [0;1;1;0;0;0;0;1;1;1;1;0;1;]
What I want is to find the location of the first zero of the first chunk with 4 OR MORE zeros appearing in the vector.
In this example the result would be:
pos = 4;
The size of the group of zeros doesn't have to be necessarily 4, this was just an example.
I cannot find a simple way to do this but most probably there's a command for for this kind of operations that I cannot recall.
Many thanks in advance,
Pedro Cavaco
Respuesta aceptada
Más respuestas (3)
Andrei Bobrov
el 21 de Jun. de 2011
EDIT
A1 = A(:)';
out = strfind([1 A1],[1 0])-1; % all groups zeros
strfind([A1 1],[0 0 1]); % all groups two zeros
...
strfind([A1 1],[zeros(1,4) 1]); % all groups 4 zeros
6 comentarios
Titus Edelhofer
el 21 de Jun. de 2011
Nice! I guess, you mean something like strfind(A1, zeros(1,n)) where n=4 was asked?
Titus
Pedro Cavaco
el 21 de Jun. de 2011
David Young
el 21 de Jun. de 2011
Even with Titus Edelhofer's correction, this still finds all occurrences, not just the first.
Andrei Bobrov
el 21 de Jun. de 2011
@Titus Edelhofer. strfind([1 A1 1],[zeros(1,4) 1])-1
Andrei Bobrov
el 21 de Jun. de 2011
speed
>> A = +(rand(10000,1)<.2);
tic, zz = char(zeros(1,4));
p = regexp(char(A(:).'), ['(?<=^|' char(1) ')' zz '(' char(1) '|$)'], 'once'); toc
Elapsed time is 0.002538 seconds.
>> tic, A1 = A(:)';strfind([A1 1],[zeros(1,4) 1]);toc
Elapsed time is 0.000652 seconds.
Andrei Bobrov
el 21 de Jun. de 2011
it's idea of Matt Fig
Gerd
el 21 de Jun. de 2011
Hi Pedro,
just programming straigforward I would use
A = [0;1;1;0;0;0;0;1;1;1;1;0;1;];
cons = 4;
indices = find(A==0);
for ii=1:numel(indices)-cons
if (indices(ii+1)-indices(ii) == 1) && (indices(ii+2)-indices(ii+1)==1) && indices(ii+3)-indices(ii+2)==1
disp(indices(ii));
end
end
Result is 4
Gerd
3 comentarios
David Young
el 21 de Jun. de 2011
You could put a "break" in the conditional to make this more efficient, since only the first occurrence is required. Also, it's probably more useful to assign the result to a variable rather than calling disp.
Pedro Cavaco
el 21 de Jun. de 2011
Gerd
el 21 de Jun. de 2011
Hi Pedro,
I tried both solution in a .m-file(David's and mine)
Please have a look at the result.
tic;
A = [0;1;1;0;0;0;0;1;1;1;1;0;1;];
cons = 4;
indices = find(A==0);
for ii=1:numel(indices)-cons
if (indices(ii+1)-indices(ii) == 1) && (indices(ii+2)-indices(ii+1)==1) && indices(ii+3)-indices(ii+2)==1
disp(indices(ii));
end
end
t1 = toc;
tic;
A = [0;1;1;0;0;0;0;1;1;1;1;0;1;];
n = 4;
p = regexp(char(A.'), char(zeros(1, n)), 'once');
disp(p);
t2 = toc;
With your testvector the result is really fast.
David Young
el 21 de Jun. de 2011
Another approach to finding the first group of 4 or more zeros:
A = [0;1;1;1;0;0;0;0;1;1;1;1;0;1;0;0;0;1];
n = 4;
c = cumsum(A);
pad = zeros(n, 1)-1;
ppp = find([c; pad] == [pad; c]) - (n-1);
p = ppp(1)
EDIT Code corrected - n replaced by (n-1) to give correct offset.
3 comentarios
Pedro Cavaco
el 21 de Jun. de 2011
Pedro Cavaco
el 21 de Jun. de 2011
David Young
el 21 de Jun. de 2011
Sorry, you are right!
Categorías
Más información sobre Characters and Strings en Centro de ayuda y File Exchange.
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!