2016-08-15 7 views
1

I三列ベクトルを有するを含む新しい配列を作成します。Matlabの:同様の値の配列を検索し、すべての値

A = [1;2;5;9;15] 
B = [2;3;5;11;15] 
C = [5;7;11;20;25] 

IはABCのすべての要素を検索することによって、新しい列ベクトルDを作成しますすべての値を見つけ、Dで繰り返さないようにします。

私はDになりたい:

D = 
    1 
    2 
    3 
    5 
    7 
    9 
    11 
    15 
    20 
    25 

はどのようにこれを行うには?
ありがとうございます!

+5

'ユニーク([A; B; C])'? – GameOfThrows

+0

考えられる1d事前ソートされたベクトルを仮定すると[matlabでunique()を達成するための[高速な方法]の可能な複製?](http://stackoverflow.com/questions/8174578/faster-way-to-achieve-unique-in-matlab- if-assum-1d-pre-sorted-vector) – GameOfThrows

+0

ありがとうございました。 matlabに組み込まれた 'ユニーク'を使う以外の方法はありますか? – user5916581

答えて

3

は別の(超高速)の方法は、ではありません

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 

このメト:あなたは整数でのみ扱っている場合unique、無ループを使用して、 dはダブルスのために一般化することができます。

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 

しかし、(tmpで)最初の値をソートする必要性は、他の方法よりも、それが遅くなります。

+0

@ user5916581いくつかの他のテクニックを見つけることがあります[ここ](http://stackoverflow.com/questions/38941694/what-is-the-fastest-way-to-count-elements- in-an-array) – EBH

+0

このメソッドは整数値を必要とするようです。しかし、これが望まれるならば、その方法は良好な性能を有するように思われる。 – patrik

+0

@patrik一般化されたメソッドを追加しましたが、他のメソッドよりも整数の方が優れているようです。 – EBH

1

このコードは、あなたが欲しいものを行う必要があります。

% 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 

% 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) 
+0

ありがとう。 matlabに組み込まれた 'ユニーク'を使う以外の方法はありますか? – user5916581

+0

@ user5916581上記の私のソリューションをあなたの代わりに編集しました。それはおそらくユニークより遅いです... – DeeCee

1

データをソートして一意の値を確認することは可能です。これは、関数unique()を使用するのと同じくらい効率的なようです。可能であればsort()diff()を使用する利点があります。しかし、これはハードウェアに依存している可能性があります。その差は、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]); 

試験

1.9085

1.9968

+2

私はこれを[histcountsの使用](http://stackoverflow.com/a/38954226/2627163)( 'testC')と比較して自分のコンピュータでテストしました。結果は' testA' = 1.6110、 testB' = 1.5125、 'testC' = 0.1835 – EBH

関連する問題