2014-09-04 288 views
2

我有2個字符串字符串,我想按照第一個字符串排序。Matlab,根據第一個字符串排序字符串

A = {'a';'b';'c'} 
B = {'b';'a';'c'} 

idx = [2,1,3] % TO FIND 

B=B(idx); 

我想找到一種方法來找到idx ......

+0

也見[兩個向量的映射ID](http://stackoverflow.com/questions/21788606/mapping-ids-of-two-vectors/21790654#21790654) – 2014-09-04 18:18:58

回答

2

這似乎比使用ismember明顯更快(儘管肯定不如@rayryeng's answer明確)。感謝@Divakar對這個答案的糾正。

[~, indA] = sort(A); 
[~, indB] = sort(B); 
idx = indA(indB); 
+0

OH。很好的使用'sort'。我有一種使用'sort'的感覺,但我無法弄清楚如何使用另一個數組'B'。很好地完成+1。 – rayryeng 2014-09-04 16:44:24

+0

@rayryeng謝謝!事實上,玩嵌套排序會令人困惑。有時我只是嘗試組合(沒有那麼多),直到我找到那個工程:-)(順便說一句,也是+1) – 2014-09-04 16:46:04

+0

如果某些元素在A和B之間不常見,或者每個元素內部重複了元素那些細胞陣列? A = {'a';'b';'c';'d'},B = {'b';'a';'c';'a'}'。 – Divakar 2014-09-04 16:49:45

3

使用的ismember第二輸出。 ismember告訴你第一組中的值是否在第二組中的任何位置。第二個輸出告訴你如果我們發現任何東西,這些值的位置。因此:

A = {'a';'b';'c'} 
B = {'b';'a';'c'} 
[~,idx] = ismember(A, B); 

請注意,當您聲明您的單元格數組時存在小錯字。對於Aac,對於B,您在bc之間有一個冒號。爲了正確性,我在那裏放置了一個分號。

因此,我們得到:

idx = 

    2 
    1 
    3 

標杆

我們有三個非常好的算法在這裏。因此,讓我們通過做一個基準測試來看看它是如何執行的。我要做的是生成一個10000 x 1的小寫字母隨機字符數組。然後將其封裝到10000 x 1單元陣列中,其中每個單元是單個字符陣列。我用這種方法構造A,而BA中元素的隨機排列。這是我寫的爲我們做這樣的代碼:

letters = char(97 + (0:25)); 
rng(123); %// Set seed for reproducibility 
ind = randi(26, [10000, 1]); 
lettersMat = letters(ind); 
A = mat2cell(lettersMat, ones(10000,1), 1); 
B = A(randperm(10000)); 

現在......來這裏的測試代碼:

clear all; 
close all; 

letters = char(97 + (0:25)); 
rng(123); %// Set seed for reproducibility 
ind = randi(26, [10000, 1]); 
lettersMat = letters(ind); 
A = mat2cell(lettersMat, 1, ones(10000,1)); 
B = A(randperm(10000)); 

tic; 
[~,idx] = ismember(A,B); 
t = toc; 

fprintf('ismember: %f\n', t); 

clear idx; %// Make sure test is unbiased 

tic; 
[~,idx] = max(bsxfun(@eq,char(A),char(B)')); 
t = toc; 

fprintf('bsxfun: %f\n', t); 

clear idx; %// Make sure test is unbiased 

tic; 
[~, indA] = sort(A); 
[~, indB] = sort(B); 
idx = indB(indA); 
t = toc; 

fprintf('sort: %f\n', t); 

這是我得到計時:

ismember: 0.058947 
bsxfun: 0.110809 
sort: 0.006054 

路易斯門多的方法是最快的,其次是ismember,最後是bsxfun。爲了代碼緊湊,ismember是首選,但對於性能,sort更好。就個人而言,我認爲bsxfun應該贏,因爲它是一個很好用的功能;)。

+0

Th我只是一個懶惰的評論!)+1當然。 – Divakar 2014-09-04 16:28:31

+0

@Divakar - ahaha謝謝:)當我看到您的評論時,我確實會推送帖子按鈕。如果我之前看到您的評論,我就不會發布。 – rayryeng 2014-09-04 16:29:25

+0

我很高興你真的發佈!總是很高興有解釋去那裏。 – Divakar 2014-09-04 16:38:34

2

我不得不跳入水中,因爲它似乎運行時性能可能是這裏的標準:)

假設你正在處理標串(每個單元一個字符),這是我拿的作品甚至當你有AB之間未commmon元素,並使用非常強大的bsxfun,因此我真的希望這將是運行效率 -

[v,idx] = max(bsxfun(@eq,char(A),char(B)')); 
idx = v.*idx 

示例 -

A = 
    'a' 'b' 'c' 'd' 
B = 
    'b' 'a' 'c' 'e' 
idx = 
    2  1  3  0 

對於特定情況下,當你有AB之間沒有未共同的元素,它成爲一個班輪 -

[~,idx] = max(bsxfun(@eq,char(A),char(B)')) 

實施例 -

A = 
    'a' 'b' 'c' 
B = 
    'b' 'a' 'c' 
idx = 
    2  1  3 
+0

Ahahahaha,我告訴自己,Divakar很可能會採用'bsxfun'解決方案。我不認爲我確實是對的。 +1。 – rayryeng 2014-09-04 17:13:23

+0

哈哈哈,那麼我會基準:)。給我一點時間。 – rayryeng 2014-09-04 17:15:58

+0

我其實會生成一堆隨機的獨特角色! – rayryeng 2014-09-04 17:18:22

相關問題