2011-12-13 21 views
5

Có một chiến lược lệnh hoặc một dòng trong MATLAB sẽ trả về tất cả các kết hợp của các thành phần của n mảng ô, được chụp n cùng một lúc không?MATLAB: Các kết hợp của một số mảng ô bất kỳ

Một ví dụ về những gì tôi muốn đạt được:

A = {'a1','a2'}; 
B = {'b1','b2','b3'}; 
C = combinations(A,B) 
C = {'a1','b1' ; 
    'a1','b2' ; 
    'a1','b3' ; 
    'a2','b1' ; 
    'a2','b2' ; 
    ... } 

Lệnh sẽ có thể chấp nhận một số bất kỳ các đối số và kết quả trong ví dụ này sẽ có nhiều cột như có tham số cho hàm . (Tất nhiên, cú pháp ở trên chỉ có nghĩa là minh họa và bất kỳ phương pháp nào có thể tạo ra kết quả bất kể định dạng nào phù hợp với hóa đơn)

EDIT: Các câu hỏi tương tự đã được hỏi cho ma trận thay vì ô, ví dụ: link. Nhiều giải pháp trỏ đến việc gửi FEX allcomb, nhưng tất cả các giải pháp như vậy chỉ là trình bao bọc quanh ndgrid, chỉ hoạt động với đôi. Bất kỳ đề xuất nào cho tập hợp số không?

+1

Bạn có thể sử dụng một giải pháp mà làm việc cho số nguyên thiết lập và sau đó nghĩ về kết quả (các kết hợp) như các chỉ mục cho các mảng ô của bạn. – Aabaz

+2

Liên quan chặt chẽ: [Matlab - Tạo tất cả các kết hợp có thể có của các phần tử của một số vectơ] (http://stackoverflow.com/q/4165859/52738), [MATLAB: Liệt kê tất cả các kết hợp của các mục trong một số bộ tùy ý] (http://stackoverflow.com/q/6607355/52738), [Làm cách nào để tạo tất cả kết hợp các ký tự trong tập hợp văn bản?] (http://stackoverflow.com/q/5623120/52738). Hai thỏa thuận đầu tiên với các vectơ số và các giao dịch thứ ba với các mảng ký tự, nhưng giải pháp cơ bản có hiệu quả tương tự đối với mảng ô. – gnovice

Trả lời

6

Mặc dù tôi địa chỉ này trong my answer đến một related/near duplicate question, tôi đăng một phiên bản khác của giải pháp của tôi ở đây kể từ khi nó xuất hiện bạn muốn có một giải pháp tổng quát , và câu trả lời khác của tôi là cụ thể cho trường hợp của ba bộ đầu vào. Dưới đây là một chức năng mà nên làm những gì bạn muốn cho bất kỳ số lượng đầu vào mảng di động:

function combMat = allcombs(varargin) 
    sizeVec = cellfun('prodofsize', varargin); 
    indices = fliplr(arrayfun(@(n) {1:n}, sizeVec)); 
    [indices{:}] = ndgrid(indices{:}); 
    combMat = cellfun(@(c,i) {reshape(c(i(:)), [], 1)}, ... 
        varargin, fliplr(indices)); 
    combMat = [combMat{:}]; 
end 

Và đây là cách bạn sẽ gọi nó là:

>> combMat = allcombs(A, B) 

combMat = 

    'a1' 'b1' 
    'a1' 'b2' 
    'a1' 'b3' 
    'a2' 'b1' 
    'a2' 'b2' 
    'a2' 'b3' 
+0

Cảm ơn bạn vì câu trả lời rất hữu ích, @gnovice. – foglerit

5

Một chiến lược 2 dòng:

A = {'a1','a2'}; 
B = {'b1','b2','b3'}; 

[a b]=ndgrid(1:numel(A),1:numel(B)); 
C= [A(a(:))' B(b(:))'] 

C = 
    'a1' 'b1' 
    'a2' 'b1' 
    'a1' 'b2' 
    'a2' 'b2' 
    'a1' 'b3' 
    'a2' 'b3' 
+0

Rất đơn giản và sạch sẽ, tôi thích nó rất nhiều. Tôi chấp nhận câu trả lời của gnovice cho tính tổng quát, nhưng câu trả lời của bạn rất hữu ích để hiểu anh ấy. – foglerit

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