2013-04-19 17 views
5

Ho due array di celle di stringhe come segueControllare se array di celle è un sottoinsieme di un nother in Matlab

A={{a,b},{c},{d,e}} 
B={{a,b},{c,d},{e}} 

voglio verificare se A è un sottoinsieme di B, il che significa che ogni cellula in A ha una super-cella in B. Nell'esempio dato non è dato che A contiene {d, e} mentre B non ha alcuna cella che ha quegli o più elementi. Penso che ismember dovrebbe essere utile in questo caso, ma non ho potuto scrivere la logica.

Grazie!

risposta

4

ne dite qualcosa di simile:

function tf = is_subset(A,B) 
    narginchk(2,2) 
    assert(iscell(A) && all(cellfun(@iscellstr,A))); 
    assert(iscell(B) && all(cellfun(@iscellstr,B))); 

    for ia=1:numel(A) 
     tf = false; 
     for ib=1:numel(B) 
      if all(ismember(A{ia},B{ib})); 
       tf = true; 
       break 
      end 
     end 
     if ~tf 
      break 
     end 
    end 
end 

Con

[a,b,c,d,e] = deal('1','2','3','4','5'); 

A = {{a,b},{c},{d,e}}; 
B = {{a,b},{c,d},{e}}; 
is_subset(A,B)    %# false 

B = {{a,b},{c,d,e},{e}}; 
is_subset(A,B)    %# true 
+0

Breaking the loop più breve tempo possibile dovrebbe portare ad un miglioramento delle prestazioni piuttosto grande nel corso degli approcci basati 'cellfun' (compreso il mio). – Pursuit

+0

funziona come per magia grazie! – Evan

2

Supponendo a, b ecc sono le stringhe che si possa fare la seguente:

Per ogni cella di un ciclo attraverso la B e vedere se c'è una cella in B per cui tutti gli elementi nella cella sono membri. Ecco un esempio:

A={{'abc','b'},{'c'},{'d','e'}}; 
B={{'aabc','b'},{'c','d'},{'d','e'}}; %Remove the first a to return true 


subset = true; 
for i = 1:length(A) 
    found = false; 
    for j = 1:length(B) 
     found = found || all(ismember(A{i},B{j})); 
    end 
    subset = subset && found; 
end 
subset 
+0

funziona molto bene grazie mille – Evan

2

Quali sono i tipi di a, b, ecc.? Se sono stringhe, è possibile utilizzare setdiff per verificare se un set è contenuto in un altro. L'uso appropriato di cellfun e any o all dovrebbe farlo. In questo modo:

all(cellfun(@(a)any(cellfun(@(b)isempty(setdiff(a,b)),B)),A)) 

Se sono un altro tipo, è possibile effettuare un semplice m-file per verificare la presenza di un super-cella. Sostituire isempty(setdiff(a,b)) con una chiamata a questa funzione. Dovrà scorrere gli elementi di a e verificare per ognuno se esiste in b.

+0

Grazie, il tuo codice sembra funzionare ma non riesco a capirlo .. puoi spiegarlo brevemente? – Evan

+0

'isempty (setdiff (a, b))' verifica se 'b' è un superset di' a'. Le due celle cell camminano sopra gli elementi di 'A' e' B'. Il risultato finale è vero se tutti gli elementi di 'A' possono trovare almeno un elemento di' B' che è un superset. – nhowe

7

Dato A e B

A={{'a','b'},{'c'},{'d','e'}} 
B={{'a','b'},{'c','d'},{'e'}} 

Possiamo definire una funzione isSubset, come segue:

isSubset = @(superSet,subSet)isempty(setdiff(subSet, superSet)); 

e testarlo:

isSubset(B{1}, A{1}) %true 
isSubset(B{2}, A{2}) %true 
isSubset(B{3}, A{3}) %false 

Ora possiamo usare isSubSet e cellfun per definire una funzione isSubSetOfAny, che controlla per vedere se un particolare sottoinsieme è un sottoinsieme di qualsiasi di un insieme di insiemi, in questo modo:

isSubSetOfAny = @(superSetSet, subSet) any(cellfun(@(x)isSubset(x, subSet), superSetSet)); 

E provarlo:

isSubSetOfAny(B, A{1}) %True 
isSubSetOfAny(B, A{2}) %True 
isSubSetOfAny(B, A{3}) %True 

Ora possiamo usare isSubSetOfAny più cellfun (di nuovo) per definire isEachMemberASubsetOfAny, che esegue l'operazione descritta:

isEachMemberASubsetOfAny = @(superSetSet, subSetSet) all(cellfun(@(x)isSubSetOfAny(superSetSet, x), subSetSet)); 

e testarlo:

isEachMemberASubsetOfAny(B, A) %Returns false 

A_1 = {{'a','b'},{'c'},{'e'}}; %Define a variant of `A` 
isEachMemberASubsetOfAny(B, A_1) %Returns false 
+0

+1 ben spiegato step-by-step – Amro

+0

molto utile grazie! – Evan

Problemi correlati