How to quickly find out the repeat integers in an array?

1 回表示 (過去 30 日間)
Benson Gou
Benson Gou 2021 年 6 月 3 日
コメント済み: Benson Gou 2021 年 6 月 4 日
Dear All,
I have an array A which contains repeat intergers (entries). For example, A = [4 20 5 4 7 5 9 5 31]. I want to find out the repeat elements {4, 5} and their locations.
Thanks.
Benson

採用された回答

Akira Agata
Akira Agata 2021 年 6 月 3 日
I believe it's time to use accumarray function!
How about the following?
A = [4 20 5 4 7 5 9 5 31];
B = accumarray(A',1);
pt = find(B >= 2);
loc = arrayfun(@(x) find(x == A),pt,'UniformOutput',false);
tResult = table(pt,loc,'VariableNames',{'Value','Location'});
The result is like this:
>> tResult
tResult =
2×2 table
Value Location
_____ _________
4 {[ 1 4]}
5 {[3 6 8]}
  1 件のコメント
Walter Roberson
Walter Roberson 2021 年 6 月 3 日
At the time I was composing my own reply, I didn't think anyone else would give an accumarray solution ;-)
There are a few differences between the above and my first solution:
  • my version supports negative integers
  • I "compress" the range of values in a sense: if the mininum integer happens to be large, a straight accumarray could waste a lot of space, whereas my version does not use up any space between 0 and the lowest integer
  • but both versions potentially waste a lot of space: if for example A was [1 1e6+1 2e6+1] then both of them waste a lot of memory
  • we handle the matches differently. Akira's version searches through the data once plus one time for every unique value; my version searches through the data once

サインインしてコメントする。

その他の回答 (1 件)

Walter Roberson
Walter Roberson 2021 年 6 月 3 日
A = [4 20 5 4 7 5 9 5 31]
A = 1×9
4 20 5 4 7 5 9 5 31
mA = min(A(:)) - 1;
At = A(:) - mA;
locs = accumarray(At, (1:length(At)), [], @(V) {V.'});
dups = cellfun(@length,locs) > 1;
info = [num2cell(At(dups)+mA), locs(dups)]
info = 2×2 cell array
{[ 4]} {[ 1 4]} {[20]} {[3 6 8]}
... but most people might find that too obscure. Less obscure might be
[G, uA] = findgroups(A);
info = cell(0,2);
for K = 1 : max(G)
matches = find(G == K);
if length(matches) > 1
info(end+1,:) = {uA(K), matches};
end
end
info
info = 2×2 cell array
{[4]} {[ 1 4]} {[5]} {[3 6 8]}
  1 件のコメント
Benson Gou
Benson Gou 2021 年 6 月 4 日
Hello, Walter,
Thanks a lot for your great help. You have a good weekend!
Benson

サインインしてコメントする。

カテゴリ

Help Center および File ExchangeCall Python from MATLAB についてさらに検索

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by