Search code examples
matlabvectorsubsetcell-arrayset-intersection

how to get the intersection of many different length cell vectors in matlab


I have n different length cell vectors, call it c{i}, i=1,2,...,n.

I wanna know if there any c{j} is the subset of c{i}, for example:

c{1}=[1 2 3 4 5 6]; c{2}=[1 3 5 7];c{3}=[2 4 6 8];
c{4}=[1 4 6];c{5}=[3 7];

then I hope I can find that c{4} is subset of c{1}, c{5} is subset of c{2}.

I used two for loops with intersect function can process it, but I hope I can use at most one loop to process it, is there any way can achieve it?


Solution

  • Building on the other answers, you can also use ismember:

    sets = {[1 2 3 4 5 6], [1 3 5 7], [2 4 6 8], [1 4 6], [3 7]};
    
    N = numel(sets);          % number of sets
    idx = nchoosek(1:N,2);    % indices of combinations
    subsets = false(N,N);
    for i = 1:size(idx,1)
        a = idx(i,1); b = idx(i,2);
    
        % check that set A is a subset of B, and the other way around as well
        subsets(a,b) = all(ismember(sets{a},sets{b}));
        subsets(b,a) = all(ismember(sets{b},sets{a}));
    end
    

    We get a logical matrix:

    >> subsets
    subsets =
         0     0     0     0     0
         0     0     0     0     0
         0     0     0     0     0
         1     0     0     0     0
         0     1     0     0     0
    

    where non-zeros indicate subset relationship:

    >> [i,j] = find(subsets)
    i =
         4
         5
    j =
         1
         2
    

    i.e c{4} is a subset of c{1}, and c{5} is a subset of c{2}

    Note: it is obvious that any set is a subset of itself, so the diagonals of subsets matrix should also be made 1. You could add that if you want using:

    subsets(1:N+1:end) = true;