25.11.2014 Views

Algorithms and Data Structures

Algorithms and Data Structures

Algorithms and Data Structures

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

N.Wirth. <strong>Algorithms</strong> <strong>and</strong> <strong>Data</strong> <strong>Structures</strong>. Oberon version 43<br />

Evidently the condition P(i-D, D) & Q(i-D) must hold before assigning j := D, if the invariant P(ij,<br />

j) & Q(i-j) is to hold thereafter. This precondition is therefore our guideline for finding an appropriate<br />

expression for D along with the condition P(i-j, j) & Q(i-j), which is assumed to hold prior to the<br />

assignment (all subsequent reasoning concerns this point of the program).<br />

The key observation is that thanks to P(i-j, j) we know that<br />

p 0 ... p j-1 = s i-j ... s i-1<br />

(we had just scanned the first j characters of the pattern <strong>and</strong> found them to match). Therefore the condition<br />

P(i-D, D) with D < j, i.e.,<br />

p 0 ... p D-1 = s i-D ... s i-1<br />

translates into an equation for D:<br />

p 0 ... p D-1 = p j-D ... p j-1<br />

As to Q(i-D), this condition follows from Q(i-j) provided ~R(i-k) for k = D+1 ... j. The validity of<br />

~R(i-k) for j = k is guaranteed by the inequality s[i] # p[j]. Although the conditions ~R(i-k) ≡ ~P(ik,<br />

M) for k = D+1 ... j-1 cannot be evaluated from the scanned text fragment only, one can evaluate the<br />

sufficient conditions ~P(i-k,k). Exp<strong>and</strong>ing them <strong>and</strong> taking into account the already found matches<br />

between the elements of s <strong>and</strong> p, we obtain the following condition:<br />

p 0 ... p k-1 ≠ p j-k ... p j-1 for all k = D+1 ... j-1<br />

that is, D must be the maximal solution of the above equation. Fig. 1.12 illustrates the function of D.<br />

examples<br />

i,j<br />

string<br />

pattern<br />

shifted pattern<br />

A A A A A C<br />

A A A A A B<br />

A A A A A B<br />

j=5, D=4, (max. shift =j-D=1)<br />

p 0… p 3 = p 1… p 4<br />

i,j<br />

A B C A B D<br />

A B C A B C<br />

A B C A B C<br />

j=5, D=2, (max. shift =j-D=3)<br />

p 0… p 1 = p 3… p 4<br />

p 0… p 2 # p 2… p 4<br />

p 0… p 3 # p 1… p 4<br />

i,j<br />

A B C D E A<br />

A B C D E F<br />

A B C<br />

j=5, D=0, (max. shift =j-D=5)<br />

p 0… p 0 # p 4… p 4<br />

p 0… p 1 # p 3… p 4<br />

p 0… p 2 # p 2… p 4<br />

p 0… p 3 # p 1… p 4<br />

Fig. 1.12. Partial pattern matches <strong>and</strong> computation of D.<br />

If there is no solution for D, then there is no match in positions below i+1. Then we set D := -1. Such a<br />

situation is shown in the upper part in Fig. 1.13.<br />

The last example in Fig. 1.12 suggests that we can do even slightly better; had the character p j been an<br />

A instead of an F, we would know that the corresponding string character could not possibly be an A, <strong>and</strong><br />

the shift of the pattern with D = -1 had to be performed in the next loop iteration (see Fig. 1.13, the lower

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!