Effacer les filtres
Effacer les filtres

How do you check if all the values in a vector are in another vector as many or more times?

25 vues (au cours des 30 derniers jours)
Hello everyone, I have a question that is probably really easy but that is driving me crazy.
Let's say I have two vectors, a small one and a long one. I would like to check if all the values that are in the small vector are also in the long vector as many or more times than in the small vector.
For example if I have a vector a=[1 1 3 4 4] and a vector b=[3 3 4 7], I would like matlab to tell me that in order to contain all the values of b, a would need a 7 and another 3.
I hope this is clear, I know of the ismember function but I can't figure how to make it work here.
Thanks infinitely for the help!

Réponse acceptée

Guillaume
Guillaume le 15 Déc 2017
fullset = [1 1 3 4 4];
baseset = [3 3 4 7];
[basesetvalues, ~, subs] = unique(baseset);
basesetcount = accumarray(subs, 1); %histogram of baseset values
[found, where] = ismember(fullset, basesetvalues);
fullsetcount = accumarray(where(found)', 1, [numel(basesetvalues), 1]);
diffcount = basesetcount - fullsetcount;
notenough = diffcount > 0;
out = table(basesetvalues(notenough).', diffcount(notenough), 'VariableNames', {'Value', 'MissingCount'})
  3 commentaires
Guillaume
Guillaume le 18 Déc 2017
I actually found another way to solve my problem
If by another way you mean KL's answer, then as per Stephen's comment it doesn't work.
It´s actually a little bit complicated
Well, what you want is not that common so there's nothing built-in to do it. It's not actually that complicated, all it does is compute the histogram of the required numbers in both sets and compare them.
Florent Dueme
Florent Dueme le 18 Déc 2017
Modifié(e) : Florent Dueme le 18 Déc 2017
Yep that´s what I meant I though there would be some built-in function to do it. I was in a bit of a hurry so I actually found a way to go around the problem instead of using these solutions, I was hoping to take a look at them later (I don´t like to just copy paste code I don´t understand I feel like i´m not learning anything that way and I´m setting myself up for some trouble). I accepted KL´s answer because it looked like it could work even though I didn´t test it myself, sorry if I mislead anyone!

Connectez-vous pour commenter.

Plus de réponses (2)

KL
KL le 15 Déc 2017
I'd recommend using intersect since you want to handle repeating elements as well. For example,
a=[1 1 3 4 4];
b=[3 3 4 7];
[~,~,ind] = intersect(a,b);
res = b(~(ismember(1:numel(b),ind)))
and the result is
res =
3 7
  3 commentaires
Stephen23
Stephen23 le 18 Déc 2017
Modifié(e) : Stephen23 le 18 Déc 2017
This answer does not work correctly because it uses intersect.
Because intersect returns only the first index if a value is repeated then the position/s of the duplicate elements will never be matched by ismember, which means that this answer is flawed and will never work. This is easy to check:
>> a = [1,1,3,3,4,4]; % note extra 3!
>> b = [3,3,4,7];
>> [~,~,ind] = intersect(a,b);
>> b(~(ismember(1:numel(b),ind)))
ans =
3 7
Whereas according to the original question, the answer should be just 7.
See Guillaume's answer for code that actually does what the question requests.
KL
KL le 18 Déc 2017
Thanks Stephen. I overlooked it completely.

Connectez-vous pour commenter.


Jos (10584)
Jos (10584) le 18 Déc 2017
Modifié(e) : Jos (10584) le 18 Déc 2017
a = [1 1 3 4 4]
b = [4 7 3 3]
[bu,~,j] = unique(b) ;
n_present = countmember(bu,a) ;
n_needed = accumarray(j,1).' ;
n_missing = max(n_needed - n_present,0) ;
% bu(k) should be added n_missing(k) times to a
disp([bu ; n_missing].')
COUNTMEMBER is a small " pick-of-the-week" utility I wrote, that can be downloaded here: https://uk.mathworks.com/matlabcentral/fileexchange/7738-countmember-a-b-

Catégories

En savoir plus sur 矩阵和数组 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!