Count common elements of two vectors, including repeats

1 回表示 (過去 30 日間)
Paolo Binetti
Paolo Binetti 2017 年 4 月 19 日
コメント済み: Paolo Binetti 2017 年 4 月 20 日
I would like to count the common elements of two vectors a and b of integers, including repeats. For example, for:
a = [9 12 8 7 8 3 3]; b = [3 2 9 9 3 5 8]; % result should be 4
a = [9 8 7 8 6]; b = [5 9 9 6 8]; % result should be 3
a = [8 1 2 3]; b = [8 8 8 4]; % result should be 1
a = [9 9 9 8 7 8 6]; b = [5 9 9 6 8 ]; % result should be 4
After several attempts with functions "intersect", "ismember", and "histc", I found a way to do it:
range_ab = [min([a b]):max([a b])];
result = sum(min(histc(a, range_ab), histc(b, range_ab)))
This solution can also be easily vectorised to compare not only a single vector a to vector b, but multiple vectors a1, a2, ... an with vector b at the same time (not shown here), which is what I will use it for.
But isn't there a simpler / more efficient way to perform this apparently simple operation of finding the common elements of two vectors?
  3 件のコメント
Andrei Bobrov
Andrei Bobrov 2017 年 4 月 19 日
if:
a = [9 9 9 8 7 8 6]; b = [5 9 9 6 8 ];
result: ?
Paolo Binetti
Paolo Binetti 2017 年 4 月 20 日
編集済み: Paolo Binetti 2017 年 4 月 20 日
Apologies, my original example was not general enough, I will edit the question in a few minutes, adding these examples:
a= [8 1 2 3]; b = [8 8 8 4]; % result should be 1
a= [9 9 9 8 7 8 6]; b = [5 9 9 6 8 ]; % result should be 4

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

回答 (1 件)

Stephen23
Stephen23 2017 年 4 月 19 日
編集済み: Stephen23 2017 年 4 月 19 日
Edited using all examples in comments or the original question.
>> a = [9,8,7,8,6]; b = [8,9,9,6,8];
>> idx = bsxfun(@eq,sort(a),sort(b(:)));
>> nnz(cumsum(idx,2) == cumsum(idx,1) & idx)
ans = 4
and
>> a = [9,8,7,8,6]; b = [5,9,9,6,8];
>> idx = bsxfun(@eq,sort(a),sort(b(:)));
>> nnz(cumsum(idx,2) == cumsum(idx,1) & idx)
ans = 3
and
>> a = [8,1,2,3]; b = [8,8,8,4];
>> idx = bsxfun(@eq,sort(a),sort(b(:)))
>> nnz(cumsum(idx,2) == cumsum(idx,1) & idx)
ans = 1
and
>> a = [9 9 9 8 7 8 6]; b = [5 9 9 6 8 ];
>> idx = bsxfun(@eq,sort(a),sort(b(:)));
>> nnz(cumsum(idx,2) == cumsum(idx,1) & idx)
ans = 4
  2 件のコメント
Andrei Bobrov
Andrei Bobrov 2017 年 4 月 19 日
+1
Paolo Binetti
Paolo Binetti 2017 年 4 月 20 日
Thank you Stephen, your solution works. Since you proposed it however I have found a different way which seems somewhat faster with long vectors. But I suspect even better ways must exist, and this is how I have recasted my post.

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

カテゴリ

Help Center および File ExchangeLogical についてさらに検索

Community Treasure Hunt

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

Start Hunting!

Translated by