2012-06-15 25 views
2

我想查找出現在矢量中以前位置的第一個元素。如何查找在矢量中看到兩次的第一個元素

例如,如果載體是:

v = [1, 3, 2, 3, 4, 5]; 

回答爲v(4) = 3,因爲3是已經見過兩次第一個元素。
有沒有一種方法來矢量化這個操作?

更新:
這是我目前的解決方案,你有更好的建議嗎?

[s o] = sort(v); % sort the array 
d = diff(s);  % the first zero corresponds to the first repetitive element 
d = find(d == 0); 

o(d(1) + 1)是已經看過兩次的第一個元素的索引。

新更新:
繼@ mwengler的解決方案,現在我上來解決找到一個矩陣中的每一行的第一個重複的元素。

function vdup = firstDup(M) 
    [SM Ord] = sort(M, 2); % sort by row 
    [rows cols] = find(~diff(SM, 1, 2)); % diff each row, and find indices of the repeated elements in sorted rows 
    Mask = (size(M,2) + 1) * ones(size(M)); % create a Mask matrix with all size(M,2)+1 
    ind = sub2ind(size(Ord), rows, cols+1); % add 1 to the column indices 
    Mask(ind) = Ord(ind); % get the original indices of each repeated elements in each row 
    vdup = min(Mask, [], 2); % get the minimum indices of each row, which is the indices of first repeated element 
+4

在您更新的解決方案上,我會指出,對於v = [1 3 4 4 3 5],您將得到答案5,因爲代碼不返回_first_重複,它返回_smallest_重複(因爲排序) – Steve

+0

好點子。謝謝! – Fashandge

回答

3

這將工作。 @Steve在您的更新解決方案中指出了一個錯誤。

[~, ~, Iv] = unique(v, 'stable'); 
idx = find(diff(Iv)-1, 1)+1; 
el = v(idx); 

在此之後,el將包含第一重複元件在vidx將是其在v索引。

首先您使用stable unique來查找唯一元素。第二個輸出參數包含每個唯一元素的原始索引。然後運行diff(Iv) - 1以查找原始索引中的跳轉。您使用find(, 1)獲取第一個元素並添加一個以獲取原始向量中的索引。索引到原始矢量中以獲取所需的元素。

+0

+1,但我認爲你應該把它分成兩步,因爲OP也有興趣獲得索引以及值:'idx = find(diff(Iv)-1,1)+ 1' then el = v(idx)' – Amro

+0

好電話@Amro - 完成!謝謝。 – Ansari

+2

對於老版本的MATLAB('stable'選項在R2012a中引入),使用'[〜,Iv] = unique(v,'first'); Iv = sort(Iv);'而不是第一行。請參閱此[問題](http://stackoverflow.com/q/3065387/97160) – Amro

-1

存儲在一個哈希表,你可以檢查已經有內容?

類似:

If (hash.hasValue(i)) 
    return true; 
else 
    hash.insert(i, 1); 
    return false; 

其中i是關鍵,位置,並且可以只包含簡單的東西,有點例如允許小結構尺寸。

+0

與一般編程類似於Java,C++的編程人員不同,我認爲hash在matlab中會很慢 – Fashandge

+1

並不是真的,MATLAB使用Java,所以它會像Java本身一樣慢/快。這不是原因,這不是做這件事的最好方法。 – Ansari

+0

安薩里出於好奇,能否向我解釋未來? – Fallenreaper

1

答案@Fash最初提出的ALMOST作品。進一步說了他的路徑:

sv = sort(v); 
repeated = sv(~diff(sv)); 
ifr = find(ismember(v,repeated),'first'); 
ir2 = find(v==v(ifr)); 
index_desired = ir2(2); 
value_desired = v(index_desired); 
+0

非常感謝!你的答案几乎可行。繼續往下走,我甚至可以得到解決方案,即使是返回MATRIX每行的第一個重複元素!看到我更新的問題。 – Fashandge

1
idx = find(any(triu(bsxfun(@eq, v, v.'), 1)), 1); 
el = v(idx); 

這是如何工作的:bsxfun(...)相互比較的v每個條目。 triu(...,1)只保留與之前的元素的匹配項(僅保留高於對角線的值)。 any告訴哪些條目與某些以前的條目匹配。 find(...,1)給出了第一個這樣的條目的索引。

相關問題