Reputation: 87
I have three column vectors:
A = [1;2;5;9;15]
B = [2;3;5;11;15]
C = [5;7;11;20;25]
I want to create a new column vector D
by searching through all the elements of A
B
C
, finding all the values and avoid repeating them in D
.
I want D
to be:
D =
1
2
3
5
7
9
11
15
20
25
How to do this?
Thanks!
Upvotes: 1
Views: 132
Reputation: 10450
Here is another (super-fast) way, not using unique
, and no loops, if you are dealing only with integers:
A = [1;2;5;9;15];
B = [2;3;5;11;15];
C = [5;7;11;20;25];
tmp = [A;B;C]; % concat the vectors
R = min(tmp):max(tmp)+1; % the range of the values
ind = histcounts(tmp,R)>0; % find all elements within tmp
D = R(ind).' % extract the relevant values
This method could be generalized for doubles:
A = [1.2;2.62;5.74;9.29;15.31];
B = [2.3;3;5;9.29;15.31];
C = [1.2;2.62;11;20;25];
tmp = sort([A;B;C]); % concat and sort the vectors
R = [tmp; max(tmp)+1]; % the range of the values
ind = histcounts(tmp,R)>0; % find all elements within tmp
D = tmp(ind) % extract the relevant values
However, the need to sort the values first (in tmp
) makes it slower than the other methods.
Upvotes: 3
Reputation: 4558
It is possible to sort the data and check the the unique values. This seems to be about as efficient as using the function unique()
. Possibly with an advantage for using sort()
and diff()
. This may however be dependent on hardware and the difference is fairly insignificant, taking into account the simplicity of D = unique([A;B;C]);
.
function test()
% A=[1;2;5;9;15];
% B=[2;3;5;11;15];
% C=[5;7;11;20;25];
A = 500*rand(10000000,1);
B= 500*rand(10000000,1);
C = 500*rand(10000000,1);
f1 = @() testA(A,B,C);
f2 = @() testB(A,B,C);
time1 = timeit(f1,1);
time2 = timeit(f2,1);
disp(time1);
disp(time2);
function D = testA(A,B,C)
d = sort([A;B;C]);
idx = diff(d);
D = d([1;idx]>0);
function D = testB(A,B,C)
D = unique([A;B;C]);
test
1.9085
1.9968
Upvotes: 1
Reputation: 320
This code should do what you want:
% Your sample arrays
A=[1;2;5;9;15]
B=[2;3;5;11;15]
C=[5;7;11;20;25]
% [A,B,C] concatenates the arrays to one single array
% Unique finds unqiues values in the input array
[D, IA, ID] = unique([A,B,C]);
disp(D);
% D = array with unique values
% ID = array with unique natural number assigned to equal values for the
% original array
% IA = array that can be referenced against ID to find the value in the
% original array
% ID and IA can be used to recreate the original array
Solution without using "unique", this is probably less efficient:
% SOLUTION WITHOUT USING UNIQUE
% Your variables
A=[1;2;5;9;15];
B=[2;3;5;11;15];
C=[5;7;11;20;25];
% Allocate a temporary array with your arrays concatenated
temp = sort([A;B;C]);
rep_count = 0; % Count number of repeat values
% Allocate a blank array for your output
D = zeros(length(temp),1);
D(1) = temp(1); % Initialise first element (is always unique)
% Iterate through temp and output unqiue values to D
for i = 2:length(temp)
if (temp(i) == D(i-1-rep_count))
rep_count = rep_count+1;
else
D(i-rep_count) = temp(i);
end
end
% Remove zeros at the end of D
D = D(1:length(D)-rep_count);
disp(D)
Upvotes: 1