How to find a chunk of a certain number of zeros inside a vector
Show older comments
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
Accepted Answer
More Answers (3)
Andrei Bobrov
on 21 Jun 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 Comments
Titus Edelhofer
on 21 Jun 2011
Nice! I guess, you mean something like strfind(A1, zeros(1,n)) where n=4 was asked?
Titus
Pedro Cavaco
on 21 Jun 2011
David Young
on 21 Jun 2011
Even with Titus Edelhofer's correction, this still finds all occurrences, not just the first.
Andrei Bobrov
on 21 Jun 2011
@Titus Edelhofer. strfind([1 A1 1],[zeros(1,4) 1])-1
Andrei Bobrov
on 21 Jun 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
on 21 Jun 2011
it's idea of Matt Fig
Gerd
on 21 Jun 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 Comments
David Young
on 21 Jun 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
on 21 Jun 2011
Gerd
on 21 Jun 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
on 21 Jun 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 Comments
Pedro Cavaco
on 21 Jun 2011
Pedro Cavaco
on 21 Jun 2011
David Young
on 21 Jun 2011
Sorry, you are right!
Categories
Find more on Characters and Strings in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!