Matlab находит все ячейки, содержащие каждую строку в другом массиве ячеек, как можно быстрее
Представьте, что у вас есть две ячейки
A={'a','b','b','c','d','e'}
B={'a','b','c','d','e','f'}
и вы хотите (как можно быстрее) получить ячейку индексов общих элементов
например
{1,2,2,3,4,5}
индексы в элементах B
{1,[2,3],4,5,6,[]}
индексы в A для элементов B
как бы ты это сделал?
2 ответа
Вот как бы я это сделал:
A = {'a','b','b','c','d','e'};
B = {'a','b','c','d','e','f'};
[~, ~, lab] = unique([A B]); % unique integer labels of elements in A and B
labA = lab(1:numel(A)); % this is A with each string replaced by its label
labB = lab(numel(A)+1:end); % this is B with each string replaced by its label
comp = bsxfun(@eq, labA(:), labB(:).'); % all pair-wise comparisons
[ii, jj] = find(comp); % row and column indices of the matchings
result_AinB = accumarray(ii, jj, [numel(A) 1], @(x){sort(x(:).')}); % group jj by ii
result_BinA = accumarray(jj, ii, [numel(B) 1], @(x){sort(x(:).')}); % group ii by jj
Это дает
>> celldisp(result_AinB)
result_AinB{1} =
1
result_AinB{2} =
2
result_AinB{3} =
2
result_AinB{4} =
3
result_AinB{5} =
4
result_AinB{6} =
5
>> celldisp(result_BinA)
result_BinA{1} =
1
result_BinA{2} =
2 3
result_BinA{3} =
4
result_BinA{4} =
5
result_BinA{5} =
6
result_BinA{6} =
[]
Лично я бы использовал
[c,ia,ib]=union(A,B)
или же
[c,ia,ib]=intersect(A,B)
и обработать индексы из этих результатов. Однако это не дает вывод в требуемом формате, поскольку в нем нет дубликатов в списке
ia = [1 2 3 4 5]
Таким образом, чтобы получить его в требуемом формате, используйте ismember дважды.
Trial>> [~,ia]=ismember(A,B)
ia =
1 2 2 3 4 5
Trial>> [~,ib]=ismember(B,A)
ib =
1 2 4 5 6 0
Вот почему я бы использовал объединение или пересечение, так как вы можете получить все необходимые данные за один вызов.
Если вы хотите, чтобы в этом конкретном формате, то это должно работать
ia=cellfun(@(x) find(strcmp(x,A)),B,'UniformOutput',false)
ib=cellfun(@(x) find(strcmp(x,B)),A,'UniformOutput',false)
ia =
1×6 cell array
[1] [1×2 double] [4] [5] [6] [1×0 double]
ib =
1×6 cell array
[1] [2] [2] [3] [4] [5]