问题
I have a vector that could look like this:
v = [1 1 2 2 2 3 3 3 3 2 2 1 1 1];
that is, the number of equal elements can vary, but they always increase and decrease stepwise by 1.
What I want is an easy way to be left with a new vector looking like this:
v2 = [ 1 2 3 2 1];
holding all the different elements (in the right order as they appear in v
), but only one of each. Preferably without looping, since generally my vectors are about 10 000 elements long, and already inside a loop that's taking for ever to run.
Thank you so much for any answers!
回答1:
You can use diff for this. All you're really asking for is: Delete any element that's equal to the one in front of it.
diff
return the difference between all adjacent elements in a vector. If there is no difference, it will return 0
. v(ind~=0)
will give you all elements that have a value different than zero. The 1
in the beginning is to make sure the first element is counted. As diff
returns the difference between elements, numel(diff(v)) = numel(v)-1
.
v = [1 1 2 2 2 3 3 3 3 2 2 1 1 1];
ind = [1 diff(v)];
v(ind~=0)
ans =
1 2 3 2 1
This can of course be done in a single line if you want:
v([1, diff(v)]~=0)
回答2:
You could try using diff
which, for a vector X
, returns [X(2)-X(1) X(3)-X(2) ... X(n)-X(n-1)]
(type help diff
for details on this function). Since the elements in your vector always increase or decrease by 1, then
diff(v)
will be a vector (of size one less than v
) with zeros and ones where a one indicates a step up or down. We can ignore all the zeros as they imply repeated numbers. We can convert this to a logical array as
logical(diff(v))
so that we can index into v
and access its elements as
v(logical(diff(v)))
which returns
1 2 3 2
This is almost what you want, just without the final number which can be added as
[v(logical(diff(v))) v(end)]
Try the above and see what happens!
来源:https://stackoverflow.com/questions/24327771/remove-duplicates-appearing-next-to-each-other-but-keep-it-if-it-appears-again