How to find a chunk of a certain number of zeros inside a vector

3 visualizzazioni (ultimi 30 giorni)
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

Risposta accettata

David Young
David Young il 21 Giu 2011
A = [0;1;1;0;0;0;0;1;1;1;1;0;1;]
n = 4;
To find the first group of 4 or more zeros:
p = regexp(char(A.'), char(zeros(1, n)), 'once')
To find the first group of exactly 4 zeros:
zz = char(zeros(1,n));
p = regexp(char(A.'), ['(?<=^|' char(1) ')' zz '(' char(1) '|$)'], 'once')
  5 Commenti
David Young
David Young il 21 Giu 2011
There are two solutions in this answer. The first of them works for the case of n or more zeros. The ?<= is a lookbehind operator to ensure that the match is at the start of the group of zeros - there is a requirement that the character before the zeros is char(1) or the start of the string. See doc regexp and follow the link to "Regular Expressions" for more details. You don't need this for the simple solution which finds groups of 4 or more zeros.
David Young
David Young il 21 Giu 2011
By the way, in the case of n or more zeros, it's not obvious whether to use my first answer, with regexp, or Andrei's answer, with strfind. For very long strings, it may be faster to use regexp because of its 'once' option; however, strfind is simpler and will have a lower overhead.

Accedi per commentare.

Più risposte (3)

Andrei Bobrov
Andrei Bobrov il 21 Giu 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 Commenti
Andrei Bobrov
Andrei Bobrov il 21 Giu 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.

Accedi per commentare.


Gerd
Gerd il 21 Giu 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 Commenti
Pedro Cavaco
Pedro Cavaco il 21 Giu 2011
Gerd, in your solution you have this big IF condition. Will it still work if 'cons' becomes say 100 or would you have to include more && (indices(ii+4)-indices(ii+3)==1) .... ?
Gerd
Gerd il 21 Giu 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.

Accedi per commentare.


David Young
David Young il 21 Giu 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 Commenti
Pedro Cavaco
Pedro Cavaco il 21 Giu 2011
But like you said on your first answer it is much faster with the
regexp!!! :D

Accedi per commentare.

Categorie

Scopri di più su Characters and Strings in Help Center e File Exchange

Community Treasure Hunt

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

Start Hunting!

Translated by