2013-04-19 36 views
5

Tôi có hai mảng di động của chuỗi như sauKiểm tra xem mảng di động là một tập hợp con của một Nother trong Matlab

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

Tôi muốn kiểm tra nếu A là một tập hợp con của B, có nghĩa là mỗi tế bào trong A có một siêu tế bào trong B. Trong ví dụ đã cho, nó không phải là vì A chứa {d, e} trong khi B không có bất kỳ ô nào có các phần tử đó hoặc nhiều hơn. Tôi nghĩ rằng ismember nên hữu ích trong trường hợp này, nhưng tôi chỉ không thể viết ra logic.

Cảm ơn bạn!

Trả lời

4

Làm thế nào về một cái gì đó như:

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 

Với

[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

Phá vỡ vòng càng sớm càng tốt sẽ dẫn đến một sự cải thiện hiệu suất khá lớn so với 'cách tiếp cận dựa cellfun' (bao gồm cả của riêng tôi). – Pursuit

+0

hoạt động giống như ma thuật cảm ơn bạn! – Evan

2

Giả sử a, b vv được chuỗi bạn có thể làm như sau:

Đối với mỗi tế bào của Một vòng lặp thông qua B và xem liệu có một ô trong B mà tất cả các phần tử trong ô là thành viên hay không. Dưới đây là một ví dụ:

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

hoạt động rất tốt nhờ rất nhiều – Evan

2

các loại a, b, vv là gì? Nếu chúng là các chuỗi, bạn có thể sử dụng setdiff để kiểm tra xem một tập hợp có nằm trong một bộ khác hay không. Việc sử dụng thích hợp cellfunany hoặc all nên thực hiện. Giống như vậy:

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

Nếu chúng là một loại khác, bạn có thể tạo một tệp m đơn giản để kiểm tra siêu di động. Thay thế isempty(setdiff(a,b)) bằng một cuộc gọi đến chức năng này. Nó sẽ phải lặp qua các phần tử của a và kiểm tra từng phần tử có tồn tại trong b hay không.

+0

Cảm ơn bạn mã của bạn dường như đang làm việc nhưng tôi không thể hiểu nó .. bạn có thể mở nó một thời gian ngắn không? – Evan

+0

'isempty (setdiff (a, b))' kiểm tra xem 'b' là một siêu của' a'. Hai cellfuns đi qua các phần tử của 'A' và' B'. Kết quả cuối cùng là đúng iff tất cả các phần tử của 'A' có thể tìm thấy ít nhất một phần tử của' B' là một phần tử siêu lớn. – nhowe

7

Với A và B

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

Chúng ta có thể định nghĩa một hàm isSubset, như sau:

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

Và kiểm tra nó:

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

Bây giờ chúng ta có thể sử dụng isSubSetcellfun để xác định một hàm isSubSetOfAny, mà sẽ kiểm tra xem một tập hợp con đặc biệt là một tập hợp con của bất kỳ một tập hợp các bộ, như thế này:

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

Và kiểm tra nó:

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

Bây giờ chúng tôi có thể sử dụng isSubSetOfAny cộng cellfun (một lần nữa) để xác định isEachMemberASubsetOfAny, thực hiện thao tác bạn mô tả:

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

Và kiểm tra nó:

isEachMemberASubsetOfAny(B, A) %Returns false 

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

+1 cũng được giải thích từng bước – Amro

+0

rất hữu ích cảm ơn bạn! – Evan

Các vấn đề liên quan