Используя идею @ gnovice о получении всех комбинаций с помощью nchoosek , я предлагаю еще два решения:
- один использует ismember (как отмечено @ loren )
- другой использует bsxfun с ручкой функции eq
Единственное отличие состоит в том, что пересекает сортирует и сохраняет только уникальные общие ключи.
a = randi(30, [100 20]);
%# a = sort(a,2);
comparisons = nchoosek(1:size(a,1),2);
N = size(comparisons,1);
keys1 = cell(N,1);
keys2 = cell(N,1);
keys3 = cell(N,1);
tic
for i=1:N
keys1{i} = intersect(a(comparisons(i,1),:),a(comparisons(i,2),:));
end
toc
tic
for i=1:N
query = a(comparisons(i,1),:);
set = a(comparisons(i,2),:);
keys2{i} = query( ismember(query, set) ); %# unique(...)
end
toc
tic
for i=1:N
query = a(comparisons(i,1),:);
set = a(comparisons(i,2),:)';
keys3{i} = query( any(bsxfun(@eq, query, set),1) ); %'# unique(...)
end
toc
... со следующими временными сравнениями:
Elapsed time is 0.713333 seconds.
Elapsed time is 0.289812 seconds.
Elapsed time is 0.135602 seconds.
Обратите внимание, что даже предварительно отсортировав a
и добавив вызов к unique
внутри циклов (прокомментированных частей), эти два метода все еще быстрее, чем intersect
.