How to find a chunk of a certain number of zeros inside a vector
Ältere Kommentare anzeigen
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
Akzeptierte Antwort
Weitere Antworten (3)
Andrei Bobrov
am 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 Kommentare
Titus Edelhofer
am 21 Jun. 2011
Nice! I guess, you mean something like strfind(A1, zeros(1,n)) where n=4 was asked?
Titus
Pedro Cavaco
am 21 Jun. 2011
David Young
am 21 Jun. 2011
Even with Titus Edelhofer's correction, this still finds all occurrences, not just the first.
Andrei Bobrov
am 21 Jun. 2011
@Titus Edelhofer. strfind([1 A1 1],[zeros(1,4) 1])-1
Andrei Bobrov
am 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
am 21 Jun. 2011
it's idea of Matt Fig
Gerd
am 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 Kommentare
David Young
am 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
am 21 Jun. 2011
Gerd
am 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
am 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 Kommentare
Pedro Cavaco
am 21 Jun. 2011
Pedro Cavaco
am 21 Jun. 2011
David Young
am 21 Jun. 2011
Sorry, you are right!
Kategorien
Mehr zu Characters and Strings finden Sie in Hilfe-Center und File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!