2013-04-19 11 views
5

Mam dwie tablice komórkowe ciągi następującoSprawdź, czy tablica komórka jest podzbiorem nother w Matlab

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

Chcę sprawdzić, jeśli A jest podzbiorem B, co oznacza, że ​​każda komórka w ma super-komórka w B. W podanym przykładzie nie jest, ponieważ A zawiera {d, e}, podczas gdy B nie ma żadnej komórki, która ma te lub więcej elementów. Myślę, że ismember powinno być przydatne w tym przypadku, ale po prostu nie mogłem zapisać logiki.

Dziękujemy!

Odpowiedz

4

Jak o czymś takim:

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 

Z

[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

Przełamując pętle jak najszybciej powinno prowadzić do dość dużej poprawy osiąganych przez 'podejść opartych cellfun' (w tym moje własne). – Pursuit

+0

działa jak magia dziękuję! – Evan

2

Zakładając, a, b etc są ciągi można wykonać następujące czynności:

Dla każdej komórki pętli przez B i zobacz, czy w komórce B znajduje się komórka, do której należą wszystkie elementy w komórce. Oto przykład:

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

działa bardzo dobrze bardzo dziękuję – Evan

2

Jakie są typy a, b itp.? Jeśli są to ciągi, możesz użyć setdiff, aby sprawdzić, czy jeden zestaw jest zawarty w innym. Odpowiednie użycie cellfun i any lub all powinno to zrobić. Podobnie jak:

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

Jeśli są innego rodzaju, możesz zrobić prosty plik m, aby sprawdzić super-komórkę. Zastąp isempty(setdiff(a,b)) wywołaniem tej funkcji. Będzie musiał przejrzeć elementy z a i sprawdzić, czy istnieje w b.

+0

Dziękujemy, że Twój kod działa, ale nie mogłem go zrozumieć. Czy możesz go krótko rozwinąć? – Evan

+0

'isempty (setdiff (a, b))' sprawdza, czy 'b' jest nadzbiorem' a'. Dwa celofony przechodzą przez elementy "A" i "B". Wynik końcowy jest prawdziwy iff wszystkie elementy 'A' mogą znaleźć przynajmniej jeden element' B' który jest nadzbiorem. – nhowe

7

Biorąc A i B

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

możemy zdefiniować funkcję isSubset, co następuje:

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

i przetestować go:

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

Teraz możemy użyć isSubSet i cellfun zdefiniować funkcję isSubSetOfAny, który sprawdza, czy dany podzbiór jest podzbiorem zbioru zestawów, jak to:

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

i przetestować go:

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

Teraz możemy użyć isSubSetOfAny oraz cellfun (ponownie), aby zdefiniować isEachMemberASubsetOfAny, który wykonuje operację, którą opisujesz:

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

i przetestować go:

isEachMemberASubsetOfAny(B, A) %Returns false 

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

+1 dobrze wyjaśniony krok po kroku – Amro

+0

bardzo pomocne dziękuję! – Evan

Powiązane problemy