我有两个字符串的单元格数组,我想检查它们是否包含相同的字符串(它们不必按相同的顺序排列,也不知道它们是否具有相同的长度)。
例如:
a = {'2' '4' '1' '3'};
b = {'1' '2' '4' '3'};
或
a = {'2' '4' '1' '3' '5'};
b = {'1' '2' '4' '3'};
首先我想到了strcmp
,但它需要循环一个单元格内容并与另一个进行比较。我还通过使用类似的东西来考虑ismember
ismember(a,b) & ismember(b,a)
但是我们事先并不知道它们的长度相同(明显不平等的情况)。那么,如果不编写过多的if / else案例,你将如何以最有效的方式进行这种比较。
答案 0 :(得分:17)
您可以使用函数SETXOR,它将返回不在两个单元格数组的交集中的值。如果它返回一个空数组,则两个单元格数组包含相同的值:
arraysAreEqual = isempty(setxor(a,b));
编辑:一些绩效指标......
由于您对性能指标感到好奇,我认为我会针对Amro列出的两个解决方案测试解决方案的速度(使用ISMEMBER和STRCMP / {{ 3}})。我首先创建了两个大型单元阵列:
a = cellstr(num2str((1:10000).')); %'# A cell array with 10,000 strings
b = cellstr(num2str((1:10001).')); %'# A cell array with 10,001 strings
接下来,我将每个解决方案运行100次以获得平均执行时间。然后,我换了a
和b
并重新开始了。结果如下:
Method | Time | a and b swapped
---------------+---------------+------------------
Using SETXOR | 0.0549 sec | 0.0578 sec
Using ISMEMBER | 0.0856 sec | 0.0426 sec
Using STRCMP | too long to bother ;)
请注意,CELLFUN解决方案始终具有快速计时。如果a
的元素不在b
中,SETXOR解决方案实际上会稍快一些。这是因为ISMEMBER跳过了计算的后半部分(因为我们已经知道a
而b
不包含相同的值)。但是,如果a
中的所有值都在b
中,则short-circuit &&
解决方案会明显变慢。
答案 1 :(得分:5)
您仍然可以像使用一个小修改一样使用ISMEMBER函数:
arraysAreEqual = all(ismember(a,b)) && all(ismember(b,a))
此外,您可以将STRCMP的循环版本编写为一行:
arraysAreEqual = all( cellfun(@(s)any(strcmp(s,b)), a) )
编辑:我正在添加另一个改编自另一个SO question的第三个解决方案:
g = grp2idx([a;b]);
v = all( unique(g(1:numel(a))) == unique(g(numel(a)+1:end)) );
本着同样的精神,我进行了时间比较(使用TIMEIT功能):
function perfTests()
a = cellstr( num2str((1:10000)') ); %#' fix SO highlighting
b = a( randperm(length(a)) );
timeit( @() func1(a,b) )
timeit( @() func2(a,b) )
timeit( @() func3(a,b) )
timeit( @() func4(a,b) )
end
function v = func1(a,b)
v = isempty(setxor(a,b)); %# @gnovice answer
end
function v = func2(a,b)
v = all(ismember(a,b)) && all(ismember(b,a));
end
function v = func3(a,b)
v = all( cellfun(@(s)any(strcmp(s,b)), a) );
end
function v = func4(a,b)
g = grp2idx([a;b]);
v = all( unique(g(1:numel(a))) == unique(g(numel(a)+1:end)) );
end
并且结果的功能顺序相同(越低越好):
ans =
0.032527
ans =
0.055853
ans =
8.6431
ans =
0.022362
答案 2 :(得分:2)
查看函数intersect
MATLAB帮助说:
[c, ia, ib] = intersect(a, b)
也 返回列索引向量ia
和ib
这样c = a(ia)
和b(ib)
(或c =
a(ia,:)
和b(ib,:)).