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

4 回答 4

3

这将起作用。@Steve 指出了您更新的解决方案中的一个错误。

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

在此之后,el将包含第一个重复的元素 inv并将idx成为其 in 的索引v

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

于 2012-06-15T20:54:29.597 回答
1

@Fash 最初提出的答案几乎是可行的。沿着他的道路走得更远:

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);
于 2012-06-15T22:32:33.110 回答
1
idx = find(any(triu(bsxfun(@eq, v, v.'), 1)), 1);
el = v(idx);

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

于 2014-08-20T09:46:39.263 回答
-1

存储在一个哈希表中,您可以检查它是否已经有内容?

就像是:

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

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

于 2012-06-15T19:53:46.290 回答