2016-03-21 2 views
1

Функция output_cellstrings = choose_and_combine(varargin) может принимать произвольное количество входных данных ячейки. Количество входов и длина каждого массива строки ячейки произвольны.Как выбрать и присоединиться к любому числу строк в Matlab?

Каждый раз мы выбираем один элемент из каждого массива ячеек и присоединяем их, чтобы сделать строку как элемент строк выходных ячеек. Выход состоит из всех возможных комбинаций.

Если у нас есть k входы и их длина n1, n2 ..., nk, длина строки выходных ячеек будет n1*n2*...*nk.

Результаты должны быть, как

>> choose_and_combine({'a1','a2'},{'b1'}) 
'a1b1' 'a2b1' 

>> choose_and_combine({'a1','a2'},{'b1'},{'c1','c2'}) 
'a1b1c1' 'a1b1c2' 'a2b1c1' 'a2b1c2' 

>> choose_and_combine({'a1','a2'},{'b1','b2','b3'},{'c1','c2'}) 
'a1b1c1' 'a1b1c2' 'a1b2c1' 'a1b2c2' 'a1b3c1' 'a1b3c2' 'a2b1c1' 'a2b1c2' 'a2b2c1' 'a2b2c2' 'a2b3c1' 'a2b3c2' 
+0

Нам нужно еще немного Информация. Что ты * пытался сделать? –

+0

, так что происходит, когда у вас есть {'a1', 'a2', 'a3'}, {'b1', 'b2'} и {'c1', 'c2'}? – GameOfThrows

+0

@GameOfThrows все возможные комбинации. – Lee

ответ

3

Похоже, что вы пытаетесь создать декартово произведение этих клеточных массивов строк, т.е. объединять их всеми возможными способами, принимая одну строку из каждого входа.

Следующая функция сделана. Результирующий порядок строк немного иначе, чем в вашем примере, но я полагаю, что это не проблема:

function out = choose_and_combine(varargin) 
    indices = cellfun(@(x) 1:length(x), varargin, 'uni', false); 
    [cartProdIdx{1:length(varargin)}] = ndgrid(indices{:}); 
    combinations = cellfun(@(strs,idx) reshape(strs(idx(:)),[],1), varargin, cartProdIdx, 'uni', false); 
    out = strcat(combinations{:})'; 
end 

>> choose_and_combine({'a1','a2'},{'b1'},{'c1','c2'}) 
ans = 
    'a1b1c1' 'a2b1c1' 'a1b1c2' 'a2b1c2' 

>> choose_and_combine({'a1','a2'},{'b1'}) 
ans = 
    'a1b1' 'a2b1' 
+0

Почему это называется «декартово произведение»? – Lee

+0

Википедия: [Декартовы произведения] (https://en.wikipedia.org/wiki/Cartesian_product) –

+0

Да, выглядит такая же идея. Спасибо за информацию. – Lee

1

Просто для записи, другого возможного решения (с помощью ind2sub):

function out = choose_and_combine(varargin) 

[idx{1:nargin}] = ind2sub(cellfun(@numel, varargin), 1:prod(cellfun(@numel, varargin))); 
out = cellfun(@(x) strjoin(arrayfun(@(i) varargin{i}{x(i)}, 1:numel(varargin), 'Un', 0), ''), num2cell(cell2mat(idx')', 2), 'Un', 0); 
Смежные вопросы