MATLAB:比较字符串的单元格数组

时间:2010-07-12 19:29:00

标签: matlab string comparison vectorization cell-array

我有两个字符串的单元格数组,我想检查它们是否包含相同的字符串(它们不必按相同的顺序排列,也不知道它们是否具有相同的长度)。

例如:

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案例,你将如何以最有效的方式进行这种比较。

3 个答案:

答案 0 :(得分:17)

您可以使用函数SETXOR,它将返回不在两个单元格数组的交集中的值。如果它返回一个空数组,则两个单元格数组包含相同的值:

arraysAreEqual = isempty(setxor(a,b));



编辑:一些绩效指标......

由于您对性能指标感到好奇,我认为我会针对Amro列出的两个解决方案测试解决方案的速度(使用ISMEMBERSTRCMP / {{ 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次以获得平均执行时间。然后,我换了ab并重新开始了。结果如下:

    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跳过了计算的后半部分(因为我们已经知道ab不包含相同的值)。但是,如果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)也   返回列索引向量iaib   这样c = a(ia)b(ib)(或c =   a(ia,:)b(ib,:)).