Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/matlab/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
MATLAB:字符串单元阵列的比较_Matlab_String_Comparison_Vectorization_Cell Array - Fatal编程技术网

MATLAB:字符串单元阵列的比较

MATLAB:字符串单元阵列的比较,matlab,string,comparison,vectorization,cell-array,Matlab,String,Comparison,Vectorization,Cell Array,我有两个字符串单元格数组,我想检查它们是否包含相同的字符串(它们不必具有相同的顺序,也不知道它们是否具有相同的长度) 例如: a = {'2' '4' '1' '3'}; b = {'1' '2' '4' '3'}; 或 首先我想到了strcmp,但它需要在一个单元格内容上循环,并与另一个单元格内容进行比较。我还考虑使用类似以下内容的ismember: ismember(a,b) & ismember(b,a) 但是我们事先不知道它们的长度是相同的(显然是不相等的)。那么,在不编写太

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

例如:

a = {'2' '4' '1' '3'};
b = {'1' '2' '4' '3'};

首先我想到了strcmp,但它需要在一个单元格内容上循环,并与另一个单元格内容进行比较。我还考虑使用类似以下内容的
ismember

ismember(a,b) & ismember(b,a)

但是我们事先不知道它们的长度是相同的(显然是不相等的)。那么,在不编写太多if/else案例的情况下,如何以最有效的方式执行此比较呢

MATLAB的帮助说明:

[c,ia,ib]=也相交(a,b)
返回列索引向量
ia
ib
这样
c=a(ia)
b(ib)
(或
c=
a(ia,:)
b(ib,:)。


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

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


编辑:一些性能度量…

由于您对性能度量很好奇,我想我应该对照(使用和/)列出的两个解决方案测试我的解决方案的速度。我首先创建了两个大型单元阵列:

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 ;)

请注意,解决方案始终具有快速计时。如果
a
中的元素不在
b
中,则解决方案的运行速度实际上会稍快一些。这是由于跳过了计算的后半部分(因为我们已经知道
a
b
不包含相同的值)。但是,如果
a
中的所有值也在
b
中,则解决方案的速度明显较慢。

您仍然可以使用ISMEMBER函数,只需稍加修改:

arraysAreEqual = all(ismember(a,b)) && all(ismember(b,a))
此外,您还可以将循环版本与STRCMP一起编写为一行:

arraysAreEqual = all( cellfun(@(s)any(strcmp(s,b)), a) )

编辑:我正在添加第三个解决方案,该解决方案改编自另一个:

本着同样的精神,Im执行了时间比较(使用函数):

结果在相同的函数顺序下(越低越好):


我不知道如何从
intersect
的结果中得到解决方案,这取决于你到底要做什么。如果需要两个向量都包含相同字符串的标量布尔值,那么gnovice的解决方案就是正确的答案。为了衡量性能,您需要另一个解决方案进行比较,比如使用循环和。我想性能会非常好,但是如果您发现使用的最终成为处理过程中的瓶颈,您可以尝试查看其源代码(
键入setxor
编辑setxor
),并通过修剪一些错误检查等方式重写它。谢谢,我想我看到@Mikhail正在尝试做什么了。性能如何?当我只需要一个真/假答案时,两个集合的XOR似乎是一个昂贵的操作
arraysAreEqual = all( cellfun(@(s)any(strcmp(s,b)), a) )
g = grp2idx([a;b]);
v = all( unique(g(1:numel(a))) == unique(g(numel(a)+1:end)) );
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