1. 程式人生 > 實用技巧 >演算法導論答案

演算法導論答案

演算法導論答案

32 String Matching

32.1-2

Suppose that all characters in the pattern P are different. Show how to accelerate NAIVE-STRING-MATCHER to run in time O.n/ on an n-character text T.

Naive-Search(T,P)
for s = 1 to n – m + 1
     j = 0
     while T[s+j] == P[j] do
            j = j + 1
            if j = m     return s
     s = j + s;

該演算法實際只是會掃描整個字串的每個字元一次,所以其時間複雜度為O(n).

31.2-3

Suppose that pattern P and text T are randomly chosen strings of length m and n, respectively, from the d-ary alphabet ∑d = {0,1,2,..,d-1},where d ≧ 2.Show that the expected number of character-to-character comparisons made by the implicit loop in line 4 of the naive algorithm is

over all executions of this loop. (Assume that the naive algorithm stops comparing characters for a given shift once it finds a mismatch or matches the entire pattern.) Thus, for randomly chosen strings, the naive algorithm is quite efficient.

當第4行隱含的迴圈執行i次時,其概率P為:

  • P = 1/Ki-1 * (1-1/k), if i < m
  • P = 1/Km-1 * (1-1/k) + 1/Km , if i = m

可以計算每次for迴圈迭代時,第4行的迴圈的平均迭代次數為:

[1(1-1/k)+2(1/K)(1-1/k)+3(1/k2)(1-1/k)+…+(m-1)(1-km-2)(1-1/k) +m(1/km-1)(1-1/k) + m*(1/km)]
= 1 - 1/k + 2/k - 2/k2 + 3/k2 - 3/k3 +...+ m/km-1 - m/km + m/km
= 1 + 1/k + 1/k2 +...+ 1/km-1
= (1 - 1/Km) / (1 - 1/k)
≤ 2

所以,可知,第4行迴圈的總迭代次數為:(n-m+1) * [(1-1/Km) / (1-1/k)] ≤ 2 (n-m+1)

31.2-4

Suppose we allow the pattern P to contain occurrences of a gap character } that can match an arbitrary string of characters (even one of zero length). For example, the pattern ab}ba}c occurs in the text cabccbacbacab as

and as

Note that the gap character may occur an arbitrary number of times in the pattern but not at all in the text. Give a polynomial-time algorithm to determine whether such a pattern P occurs in a given text T, and analyze the running time of your algorithm.

該演算法只是要求判斷是否模式P出現在該字串中,那麼問題被簡化了許多。對於該問題而言,我們可以模式P中的gap為分隔符,將原字串分解為多個子字串{P1,P2,...},而後,在T中依次尋找這些字串,必須保證Pi+1在Pi之後。其虛擬碼如下:

Gap-Naive-Search(T,P)
n = T.length
m = P.length
i = 0;
j = 0;
while(i ≦ n)
   //直接刪去下一個字串前的gap字元
   while(i ≦ m && P[i] == gap)
       i++;
   if i > m  return true;
   //找到下一個需要進行匹配的子串
   k = 0;
   while(P[i+k] != gap)
       k++;
   s = Naive-Search(T[j..n],P[i..i+j-1]);
   if s == -1  return false
   i = i + s;
   j = j + k;
 
Naive-Search(T,P)
n = T.length;
m = P.length;
for s = 1 to n – m + 1
     j = 0
     while T[s+j] == P[j]  do
            j = j + 1;
     if j = m   return s
return -1