6

大きなセル配列内の文字列の小さなセル配列を見つける簡単な方法はありますか? 2 つのリストがあります。1 つは固有の要素を含み、もう 1 つは反復要素を含みます。大きな配列内の小さな配列の特定のパターンの出現全体を見つけたいです。strcmp が 2 つの cell 配列を比較することは承知していますが、それらの長さが等しい場合に限ります。私の最初の考えは、ループを使用してより大きな配列のサブセットをステップ実行することでしたが、より良い解決策が必要です。

たとえば、次のようになります。

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

4 に答える 4

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次に、これらの開始インデックスからベクトルを構築します。このベクトルを作成する 1 つの方法を次に示します。

>> 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);
于 2010-06-30T19:56:43.563 に答える
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;
于 2010-07-01T04:14:24.320 に答える
1

@gnoviceの回答では、最初の部分は次のようになります

l = grp2idx(largecellarray)';
s = grp2idx(smallcellarray)';
startIndices = strfind(l,s);
于 2010-06-30T20:02:29.930 に答える
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

(私は知っています、私は知っています、エラーチェックはありません - 私は恐ろしい人です。)

于 2010-06-30T19:31:13.723 に答える