using while-end block to find pattern in an array

Write code using a while loop that will assign to the variable numOccursSep the number of times a certain pattern of 0's and 1's occurs separately in V. The variable pattern gives the certain pattern to look for. For this problem overlap is not allowed, i.e. if pattern = [0, 1, 0] then the last 0 of an occurrence of [0, 1, 0] cannot be the rst 0 of the next occurrence. For example, if V = [0, 1, 0, 1, 0] then only one instance of [0, 1, 0] should be counted and numOccursSep should equal 1.
V = [0, 1, 0, 1, 0];
pattern = [0, 1, 0];
count = 0;
while strfind(V,pattern) == 1
count = count+1;
end
numOccursSep = count;
Normally I would use strfind(V,pattern) and then numel(strfind(V,pattern)) but I do not know how to account for the fact that overlap is not allowed. How can I do this?

9 件のコメント

dpb
dpb 2014 年 6 月 22 日
Is it a requirement to use a loop? If not, the hint is that need to look at differences between the found locations when doing the evaluation of the number of permissible hits in the return vector from strfind
I do use a loop, loop over the position of a starting substring to search and only search for the length of the pattern in the string. If found, increment the indices by length(pattern), if not then increment by one.
Rick
Rick 2014 年 6 月 22 日
Yes a loop is needed
dpb
dpb 2014 年 6 月 22 日
Since is a apparently a class assignment from the autograder, standard procedure in Answers is for the requestor to show what they've done so far...I gave a couple of hints on how one way to construct a solution with and another without. Let's see you're attempt for the looping construct...
I'll start--
L=length(pattern);
i1=1; i2=L;
count=0;
while i2<length(V)
if strfind(V(i1:i2),pattern)
...?
Rick
Rick 2014 年 6 月 22 日
yes, what I had done so far was in my original post.
dpb
dpb 2014 年 6 月 22 日
Well, that doesn't show any attempt to get past the initial solution. Where's the expansion/completion of the template I started? (BTW, I finished and tested it on your data in about six/seven additional lines. All there is another if...else...end clause to finish the job.)
Rick
Rick 2014 年 6 月 22 日
My apologies, I will try to expand upon what you did in a little while, working on another problem at the moment.
Rick
Rick 2014 年 6 月 23 日
I don't think I want to use strfind anymore. I should do an element by element comparison. Here is my code for when overlap IS allowed. Now how would I account for if overlap is NOT allowed?
numOccurs = 0;
for j = length(pattern):length(V)
if V(j-length(pattern)+1:j) == pattern;
numOccurs = numOccurs + 1;
end
Rick
Rick 2014 年 6 月 23 日
編集済み: Rick 2014 年 6 月 23 日
Is this what you meant by '' loop over the position of a starting substring to search and only search for the length of the pattern in the string. If found, increment the indices by length(pattern), if not then increment by one.'' The part j < length(V) doesnt seem to make sense to me. That is always true, but the while loop is supposed to run until a certain condition is met, of which it always is.
j=length(pattern);
numOccursSep=0;
while j < length(V)
if strfind(V(1:j),pattern)
j + length(pattern);
else
j + 1;
end
end
dpb
dpb 2014 年 6 月 23 日
編集済み: dpb 2014 年 6 月 23 日
Closer, and "sorta'" :) Note in my implementation there are two position indicators, not just one and the loop control is over the second. These two are the start:end locations for the next part of the string to search; hence the loop runs until the new end position runs past the length(searchstring). You've recast it to only one and keep searching from the beginning instead of moving the starting point along...the rest of my implementation is
count = count+1; % found a match, increment by L
i1=i2+1;i2=i2+L;
else % no match, no count, increment by 1
i1=i1+1;i2=i2+1;
end
end

サインインしてコメントする。

回答 (2 件)

dpb
dpb 2014 年 6 月 23 日

1 投票

Putting comments together since did put in the effort to try...
L=length(pattern); % keep the constant
i1=1;i2=L; % start w/ beginning of string length of pattern
count=0;
while i2<length(V)
if strfind(V(i1:i2),pattern) % found, so
count = count+1; % increment count
i1=i2+1;i2=i2+L; % next start is previous end+1, length L
else % not found, so
i1=i1+1;i2=i2+1; % look in next position
end
end
I'll still note one can use the raw output of strfind on the whole vector and post-process the found locations with diff to discover which are not disparate subsections to remove the overlapped cases.
Andrei Bobrov
Andrei Bobrov 2014 年 6 月 23 日
編集済み: Andrei Bobrov 2014 年 6 月 23 日

0 投票

m = numel(pattern);
ii = strfind(V(:)',pattern(:)');
k = ii(1);
f = ii(2:end);
count = 1;
while numel(f) >= 1
count = count + 1;
f = f((k + m - 1) < f);
k = f(1);
f = f(2:end);
end
other variant witout while loop
m = numel(pattern);
x = zeros(1,numel(V));
x(bsxfun(@plus,strfind(V(:)',pattern(:)'),(0:m-1)')) = 1;
t = sum(floor((strfind([x 0],[1 0])...
- strfind([0 x],[0 1]) + 1)/m));

カテゴリ

ヘルプ センター および File ExchangeLoops and Conditional Statements についてさらに検索

タグ

質問済み:

2014 年 6 月 22 日

編集済み:

2014 年 6 月 23 日

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by