How to find a chunk of a certain number of zeros inside a vector
    조회 수: 2 (최근 30일)
  
       이전 댓글 표시
    
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
채택된 답변
  David Young
      
 2011년 6월 21일
        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
  David Young
      
 2011년 6월 21일
				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
      
 2011년 6월 21일
				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.
추가 답변 (3개)
  Andrei Bobrov
      
      
 2011년 6월 21일
        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
  Andrei Bobrov
      
      
 2011년 6월 21일
				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
      
 2011년 6월 21일
        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
  Gerd
      
 2011년 6월 21일
				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
      
 2011년 6월 21일
        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
참고 항목
카테고리
				Help Center 및 File Exchange에서 Characters and Strings에 대해 자세히 알아보기
			
	Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!