Filter löschen
Filter löschen

Count common elements of two vectors, including repeats

1 Ansicht (letzte 30 Tage)
Paolo Binetti
Paolo Binetti am 19 Apr. 2017
Kommentiert: Paolo Binetti am 20 Apr. 2017
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 Kommentare
Andrei Bobrov
Andrei Bobrov am 19 Apr. 2017
if:
a = [9 9 9 8 7 8 6]; b = [5 9 9 6 8 ];
result: ?
Paolo Binetti
Paolo Binetti am 20 Apr. 2017
Bearbeitet: Paolo Binetti am 20 Apr. 2017
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

Melden Sie sich an, um zu kommentieren.

Antworten (1)

Stephen23
Stephen23 am 19 Apr. 2017
Bearbeitet: Stephen23 am 19 Apr. 2017
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 Kommentare
Paolo Binetti
Paolo Binetti am 20 Apr. 2017
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.

Melden Sie sich an, um zu kommentieren.

Kategorien

Mehr zu Characters and Strings finden Sie in Help Center und File Exchange

Community Treasure Hunt

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

Start Hunting!

Translated by