使用@gnovice 的想法,使用 nchoosek 获得所有组合,我提出了另外两个解决方案:
- 一个使用 ismember(如 @loren 所述)
- 另一个使用 bsxfun 和 eq 函数句柄
唯一的区别是 intersect 只对唯一的公共键进行排序和保留。
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 快。