如何找到在向量中看到过两次的第一个元素

时间:2012-06-15 19:48:38

标签: matlab duplicates vectorization

我想找到向量中先前位置出现的第一个元素。

例如,如果向量是:

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的解决方案,我现在提出解决方案,找到MATRIX每行的第一个重复元素。

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 个答案:

答案 0 :(得分:3)

这会奏效。 @Steve在更新的解决方案中指出了一个错误。

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

在此之后,el将包含v中的第一个重复元素,而idx将是v中的索引。

首先使用stable unique查找唯一元素。第二个输出参数包含每个唯一元素的原始索引。然后运行diff(Iv) - 1以查找原始索引中的跳转。使用find(, 1)获取第一个元素并添加一个元素以获取原始向量中的索引。索引到原始矢量以获得所需的元素。

答案 1 :(得分: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);

答案 2 :(得分:1)

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

如何运作:bsxfun(...)v的每个条目相互比较。 triu(...,1)仅保留与之前的元素匹配(仅保留对角线以上的值)。 any告诉哪些条目与之前的某个条目匹配。 find(...,1)给出第一个这样的条目的索引。

答案 3 :(得分:-1)

存储在哈希表中,您可以检查已有内容吗?

类似的东西:

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

其中i是关键,位置,并且可以包含一些简单的东西,例如允许小结构尺寸。