how remove tow of three consecutive same values in a vector
Show older comments
I have two vectors like this
a=[1,2,3,1,1,1,2,3,2,3,1,1,1,1,2,3,3,3,2,2,1],
where * b * is id of * a *
b=[1,2,3,11,12,13,20,21,25,27,31,32,33,34,36,40,41,42,47,48,50]
what i want to achieve is to keep the midle element of three consecutive elements or the even element if te consecuence is more than 3 elements. i want to keep the b[4] or b[11] and b[13] also the b[16]. how to achieve this?? Can any body help?
9 Comments
Azzi Abdelmalek
on 23 Apr 2014
This is not clear
DuckDuck
on 23 Apr 2014
the cyclist
on 23 Apr 2014
@effess, you say you want the middle element when there is a group of three. But then you say you want b[4]. That's the first element of the group of three, not the middle. b[5] is the middle one. Which do you want?
DuckDuck
on 23 Apr 2014
the cyclist
on 23 Apr 2014
"like in programming" (hehe).
Just remember that MATLAB is 1-based index, not 0-based.
Geoff Hayes
on 23 Apr 2014
@effess, MATLAB uses one-based array indexing so the first element in b is accessed by b(1) .
A relatively simple solution would be to just loop through all elements of a and count the number of consecutive integers that are identical starting at index i say. Upon a change in the integer, at index j say, where a(j)~=a(j-1) then you know that all integers in a from index i to index j-1 are identical.
If the count is one (i.e. (j-1)-i+1==1) then you need only copy/keep b(i). If the count is three, then just keep the middle element b(i+1), and if the count is even, then keep every other element, b(i+1:2:j-1).
What I'm not sure of, is how to handle the case of (for example) 5 consecutive integers. Do you keep the middle of the first three, and then the last: so b(3) and *b(5) (if identical from 1 to 5) or do something else? How do you expect to handle the case of 7 consecutive integers? Or 9?
the cyclist
on 23 Apr 2014
Note that taking the middle element (which is the 2nd element) of a group of 3 is a special case of the general rule of taking the even-numbered elements of groups of 3 or more.
Geoff Hayes
on 23 Apr 2014
I don't understand "..but they are not consecutive in b". I thought that it was only the consecutive integers in a that we were concerned with?
Accepted Answer
More Answers (1)
the cyclist
on 23 Apr 2014
This code is just terrible, but I think it does what you want.
a = [1,2,3,1,1,1,2,3,2,3,1,1,1,1,2,3,3,3,2,2,1];
b = [1,2,3,11,12,13,20,21,25,27,31,32,33,34,36,40,41,42,47,48,50];
d = [];
currentRunLength = 1;
for i = 2:numel(a)
if a(i)==a(i-1)
currentRunLength = currentRunLength+1;
if ((currentRunLength==2) && (i~=numel(a)) && a(i)==a(i+1)) || ((currentRunLength>=4) && mod(currentRunLength,2)==0)
d = [d,b(i)];
end
else
currentRunLength = 1;
end
end
3 Comments
Geoff Hayes
on 23 Apr 2014
Don't forget to capture, outside of the for loop, the case where consecutive identical integers are at the end of vector a i.e. currentRunLength>1.
the cyclist
on 23 Apr 2014
I think my code covers all cases. Do you have a counter-example?
Geoff Hayes
on 23 Apr 2014
My mistake - I had read your a(i)==a(i-1) as ~= and so figured that a final check would be needed.
That being said, is it only the ids of the duplicates that are to be kept (from b) or should it be the ids of the single elements as well?
Categories
Find more on Logical in Help Center and File Exchange
Products
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!