STRCMP لمصفوفات الخلايا ذات الطول غير المتكافئ في MATLAB
-
01-10-2019 - |
سؤال
هل هناك طريقة سهلة للعثور على مجموعة خلية أصغر من الأوتار داخل واحدة أكبر؟ لقد حصلت على قائمتين ، واحدة مع عناصر فريدة ، وواحدة مع عناصر متكررة. أريد أن أجد حوادث كاملة للنمط المحدد للمصفوفة الأصغر داخل أكبر. أدرك أن 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]
المحلول
يمكنك بالفعل استخدام الوظيفة إيمبور للحصول على ناقل فهرس للمكان في الخلايا 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 اعطي من قبل أمرو. طريقة أخرى لإنشائها هي:
index = cumsum([startIndices; ones(nSmall-1,numel(startIndices))]);
index = ismember(1:numel(largecellarray),index);
نصائح أخرى
إليك نسختي (استنادًا إلى إجابات كل من @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;
في Gnovice الإجابة يمكن أن يكون الجزء الأول
l = grp2idx(largecellarray)';
s = grp2idx(smallcellarray)';
startIndices = strfind(l,s);
حصلت على الحل التالي ، لكنني ما زلت أتساءل عما إذا كانت هناك طريقة أفضل للقيام بذلك:
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
(أعرف ، أنا أعلم ، لا يوجد خطأ في التحقق - أنا شخص فظيع.)