How to find a chunk of a certain number of zeros inside a vector
    4 visualizaciones (últimos 30 días)
  
       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
0 comentarios
Respuesta aceptada
  David Young
      
 el 21 de Jun. de 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 comentarios
  David Young
      
 el 21 de Jun. de 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
      
 el 21 de Jun. de 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.
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
  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.
  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
  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
Ver también
Categorías
				Más información sobre Characters and Strings en Help Center y File Exchange.
			
	Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!




