Преобразовать массив ячеек из массивов ячеек разного размера в массив ячеек из массивов ячеек размером {1xN}

Я пытаюсь заставить combnk сгенерировать все комбинации строк в ячейке. Например.:

someStrings = {'a','b','dog','goat'};
results = arrayfun(@(k) combnk(someStrings,k),1:length(someStrings),'UniformOutput',0);

Это дает мне массив ячеек 4*1 из массивов ячеек со следующими размерами:

{4x1 cell}    {6x2 cell}    {4x3 cell}    {1x4 cell}

То, что я хочу, это массив ячеек 15*1 из массивов ячеек, каждый из которых имеет размер {1xN}; то есть 4 массива ячеек размером {1,1}, 6 размером {1,2} и т. д. Как я могу сделать это эффективно?

РЕДАКТИРОВАТЬ: Хорошо, теперь я здесь:

results = transpose(arrayfun(@(k) num2cell(combnk(someStrings,k),2),1:length(someStrings),'UniformOutput',0));
finalResults = vertcat(results{:});

Можно ли превратить это в одну строку? Как вы индексируете массив ячеек, например «{:}», но в строке был создан массив ячеек?


person Nicholas Root    schedule 19.04.2015    source источник
comment
Если какой-либо из приведенных ниже ответов удовлетворил ваши требования, примите этот ответ, нажав на галочку слева.   -  person Autonomous    schedule 19.04.2015


Ответы (2)


Вы можете добиться этого следующим образом:

intermResults=cellfun(@(x) num2cell(x,2),results,'uni',0);
finalResults=vertcat(intermResults{:});

Объяснение: если вы посмотрите на свою переменную results, у вас есть эти 15 ячеек. Вам просто нужно извлечь каждую строку и сделать ее ячейкой. Это то, что делает num2cell(x,2). Оборачивая его в cellfun, я применяю его к каждой ячейке в массиве ячеек results. Теперь у вас есть ячейка 1x4, в которой каждая строка результатов преобразована в отдельную ячейку. Вам просто нужно объединить его, чтобы получить окончательный ответ. Это то, что делает vertcat(intermResults{:}).

person Autonomous    schedule 19.04.2015
comment
Это очень близко к тому, что я хочу. Однако, если я пытаюсь сделать это в одной строке, это не совсем работает. Я отредактировал свой пост с обновлением. - person Nicholas Root; 19.04.2015
comment
Моя ошибка. Теперь я разделил его на две строки. Однако посмотрите на решение @LuisMendo. Я предпочитаю это. Я дал решение, которое сохраняет ваше нетронутым и просто основывается на нем, но я думаю, что решение LuisMendo будет быстрее. - person Autonomous; 19.04.2015

Вы можете сделать это следующим образом:

m = dec2bin(1:2^numel(someStrings)-1)-'0'; %// each row contains indices of a combination
[~, s] = sort(sum(m,2)); %// compute sum of each row, sort and get sorting indices
m = m(s,:); %// sort rows according to sum
[jj, ii] = find(m.'); %'// find column indices (jj), ordered by row (ii)
result = accumarray(ii, jj, [], @(x){someStrings(x)}); %// group col indices of each row

Это дает, для вашего примера someStrings,

>> result
result = 
    {1x1 cell}
    {1x1 cell}
    {1x1 cell}
    {1x1 cell}
    {1x2 cell}
    {1x2 cell}
    {1x2 cell}
    {1x2 cell}
    {1x2 cell}
    {1x2 cell}
    {1x3 cell}
    {1x3 cell}
    {1x3 cell}
    {1x3 cell}
    {1x4 cell}

куда

>> result{1}
ans = 
    'goat'
>> result{2}
ans = 
    'dog'
>> result{3}
ans = 
    'b'
>> result{4}
ans = 
    'a'
>> result{5}
ans = 
    'dog'    'goat'
>> result{6}
ans = 
    'b'    'goat'
[...]
>> result{15}
ans = 
    'a'    'b'    'dog'    'goat'
person Luis Mendo    schedule 19.04.2015