【问题标题】:Strcmp for cell arrays of unequal length in MATLABMATLAB中不等长元胞数组的Strcmp
【发布时间】:2011-03-10 07:42:13
【问题描述】:

有没有一种简单的方法可以在较大的字符串单元格数组中找到较小的字符串单元格数组?我有两个列表,一个包含独特元素,一个包含重复元素。我想在较大的数组中找到较小数组的特定模式的全部出现。我知道 strcmp 将比较两个单元格数组,但前提是它们的长度相等。我的第一个想法是使用循环逐步遍历较大数组的子集,但必须有更好的解决方案。

例如,在下面:

smallcellarray={'string1',...
                'string2',...
                'string3'};
largecellarray={'string1',...
                'string2',...
                'string3',...
                'string1',...
                'string2',...
                'string1',...
                'string2',...
                'string3'};

index=myfunction(largecellarray,smallcellarray)

会回来

index=[1 1 1 0 0 1 1 1]

【问题讨论】:

    标签: matlab strcmp cell-array


    【解决方案1】:

    我得到了以下解决方案,但我仍然想知道是否有更好的方法来做到这一点:

    function [output]=cellstrcmpi(largecell,smallcell)
    output=zeros(size(largecell));
    idx=1;
    while idx<=length(largecell)-length(smallcell)+1
        if sum(strcmpi(largecell(idx:idx+length(smallcell)-1),smallcell))==length(smallcell)
           output(idx:idx+length(smallcell)-1)=1;
           idx=idx+length(smallcell);       
        else
            idx=idx+1;
        end
    end
    

    (我知道,我知道,没有错误检查 - 我是一个可怕的人。)

    【讨论】:

      【解决方案2】:

      您实际上可以使用函数ISMEMBER 来获取largecellarray 中的单元格在较小数组smallcellarray 中出现的索引向量,然后使用函数STRFIND(适用于两个字符串数值数组)在较大的数组中找到较小数组的起始索引:

      >> nSmall = numel(smallcellarray);
      >> [~, matchIndex] = ismember(largecellarray,...  %# Find the index of the 
                                      smallcellarray);    %#   smallcellarray entry
                                                          %#   that each entry of
                                                          %#   largecellarray matches
      >> startIndices = strfind(matchIndex,1:nSmall)  %# Starting indices where the
                                                      %#   vector [1 2 3] occurs in
      startIndices =                                  %#   matchIndex
      
           1     6
      

      然后是从这些起始索引构建向量index 的问题。这是创建此向量的一种方法:

      >> nLarge = numel(largecellarray);
      >> endIndices = startIndices+nSmall;  %# Get the indices immediately after
                                            %#   where the vector [1 2 3] ends
      >> index = zeros(1,nLarge);           %# Initialize index to zero
      >> index(startIndices) = 1;           %# Mark the start index with a 1
      >> index(endIndices) = -1;            %# Mark one index after the end with a -1
      >> index = cumsum(index(1:nLarge))    %# Take the cumulative sum, removing any
                                            %#   extra entry in index that may occur
      index =
      
           1     1     1     0     0     1     1     1
      

      使用函数BSXFUN 创建它的另一种方法是Amro。另一种创建方式是:

      index = cumsum([startIndices; ones(nSmall-1,numel(startIndices))]);
      index = ismember(1:numel(largecellarray),index);
      

      【讨论】:

      • 如果largecellarray{'string3'},这不会产生正确的结果吗?
      • @Jonas:我得到了index = 0,使用我上面的最新版本的解决方案。
      • 哦,现在我了解您的解决方案了。聪明的! +1
      • 我将此代码用于类似问题。 MATLAB 抱怨 strfind 只需要一行输入,所以我输入了 startIndices = strfind(matchIndex',1:nSmall')
      【解决方案3】:

      在@gnovice 回答第一部分可以是

      l = grp2idx(largecellarray)';
      s = grp2idx(smallcellarray)';
      startIndices = strfind(l,s);
      

      【讨论】:

      • 我不知道grp2idx。好的!但是,如果 largecellarray 中有 string0,这不会失败吗?
      • 不幸的是,这仅在smallcellarray 中的N 个条目与largecellarray 中的前N 个条目完全相同 时才有效。
      • 是的,在很多情况下它实际上会失败,因为对于 grp2idx 来说,顺序很重要。可能 ismember 函数在这里很重要。
      • 如果您将它们组合为一个单元阵列传递给grp2idx,它将解决问题..
      【解决方案4】:

      这是我的版本(基于@yuk 和@gnovice 的回答):

      g = grp2idx([S L])';
      idx = strfind(g(numel(S)+1:end),g(1:numel(S)));
      idx = bsxfun(@plus,idx',0:numel(S)-1);
      
      index = zeros(size(L));
      index(idx(:)) = 1;
      

      【讨论】:

      • +1:非常好,虽然有两件事值得一提:1) 你需要Statistics Toolbox 才能使用GRP2IDX。 2) 函数FINDSTR 似乎将被淘汰,取而代之的是STRFIND
      • @gnovice:修复了 findstr/strfind(注意参数的顺序现在很重要),我没有意识到这是一个已弃用的函数.. 谢谢
      猜你喜欢
      • 2023-03-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多