Strcmp用于MATLAB中不等长的单元阵列

时间:2010-06-30 19:21:03

标签: matlab strcmp cell-array

是否有一种简单的方法可以在较大的字符串中找到较小的字符串数组?我有两个列表,一个有独特元素,另一个有重复元素。我想在较大的数组中找到较小数组的特定模式的全部出现。我知道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]

4 个答案:

答案 0 :(得分:9)

您实际上可以使用函数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);

答案 1 :(得分:5)

这是我的版本(基于@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;

答案 2 :(得分:1)

在@gnovice中,第一部分可以是

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

答案 3 :(得分:0)

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

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

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