Count common elements of two vectors, including repeats

3 vues (au cours des 30 derniers jours)
Paolo Binetti
Paolo Binetti le 19 Avr 2017
Commenté : Paolo Binetti le 20 Avr 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 commentaires
Andrei Bobrov
Andrei Bobrov le 19 Avr 2017
if:
a = [9 9 9 8 7 8 6]; b = [5 9 9 6 8 ];
result: ?
Paolo Binetti
Paolo Binetti le 20 Avr 2017
Modifié(e) : Paolo Binetti le 20 Avr 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

Connectez-vous pour commenter.

Réponses (1)

Stephen23
Stephen23 le 19 Avr 2017
Modifié(e) : Stephen23 le 19 Avr 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 commentaires
Andrei Bobrov
Andrei Bobrov le 19 Avr 2017
+1
Paolo Binetti
Paolo Binetti le 20 Avr 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.

Connectez-vous pour commenter.

Catégories

En savoir plus sur Characters and Strings dans Help Center et File Exchange

Community Treasure Hunt

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

Start Hunting!

Translated by