Presentation is loading. Please wait.

Presentation is loading. Please wait.

算法基础 第八讲:串匹配算法 主 讲: 顾 乃 杰 教授 单 位: 计算机科学技术学院 学 期: (秋)

Similar presentations


Presentation on theme: "算法基础 第八讲:串匹配算法 主 讲: 顾 乃 杰 教授 单 位: 计算机科学技术学院 学 期: (秋)"— Presentation transcript:

1 算法基础 第八讲:串匹配算法 主 讲: 顾 乃 杰 教授 单 位: 计算机科学技术学院 学 期: 2016-2017 (秋)
算法基础 第八讲:串匹配算法 Good afternoon, ladies and gentlemen. My name is Liu gang. I’m from Dept. of Computer Science and technology, USTC. I am very glad to give my report titled “All-to-All Personalized Communication in All-Port Tori ”, which is my thesis for Master’s Degree. (20”) Name: 刘 刚 Liu Gang Class: #8 Tel: 主 讲: 顾 乃 杰 教授 单 位: 计算机科学技术学院 学 期: (秋)

2 Department of Computer Science & Technology
主要内容 The Naive Algorithm (Brute Force ) The Knuth-Morris-Pratt Algorithm The SHIFT-OR Algorithm The Boyer-Moore Algorithm The Boyer-Moore-Horspool Algorithm The Karp-Rabin Algorithm Conclusion 本教案参考了下述有关 String Searching Algorithm 的教案,在此表示感谢: 中国台湾省 国立中山大学 黃三益教授的教案 Princeton University • Kevin Wayne • Theory of Algorithms • COS 42 2018/8/26 Department of Computer Science & Technology

3 Department of Computer Science & Technology
8.0 串匹配问题 String-matching Problem: Find one occurrences of a pattern in a text ; Find out all the occurrences of a pattern in a text. Applications require two kinds of solution depending on which string, the pattern or the text, is given first. Algorithms based on the use of automata or combinatorial properties of strings are commonly implemented to preprocess the pattern and solve the first kind of problem. The notion of indexes realized by trees or automata is used in the second kind of solutions. 2018/8/26 Department of Computer Science & Technology

4 Department of Computer Science & Technology
串匹配及其应用 Some applications. Word processors. Virus scanning. Text information retrieval systems. (Lexis, Nexis) Digital libraries. Natural language processing. Specialized databases. Computational molecular biology. Web search engines. Bioinformatic. 2018/8/26 Department of Computer Science & Technology

5 Department of Computer Science & Technology
串匹配示例 n e l Search Text d n e d l Search Pattern Successful Search n e l d n e d l Search Pattern 2018/8/26 Department of Computer Science & Technology

6 Department of Computer Science & Technology
常用述语和定义 Parameters. 记文本串为 T,模式串为 P n: the length of the text. m : the length of the pattern (string). Typically, n >> m. e.g., n = 1 million, m = 1 hundred σ : the size of the alphabet. ∑ : the alphabet. Cn: the expected number of comparisons performed by an algorithm while searching the pattern in a text of length n 2018/8/26 Department of Computer Science & Technology

7 Department of Computer Science & Technology
串匹配算法概述 目前教科书上所介绍的串匹配算法基本原理是: 利用一个大小等同于模式长度的 window 对文本串进行扫描; 首先将模式串与文本串的左端对齐; 对模式串与文本串的对应字符进行对比----称为一次 attempt 在每次成功匹配或每次失配之后,将 window 右移; 重复3,4两步直到 window 的右端超出文本串的右端。 这种方法称为 sliding window mechanism. 在将文本串中的当前window部份与模式串对比时可以: 从左到右,也可以从右到左,甚至可以用特定次序。 2018/8/26 Department of Computer Science & Technology

8 Department of Computer Science & Technology
串匹配算法概述 (续) From left to right Karp and Rabin Knuth,Morris and Pratt From right to left Boyer and Moore Horspool In any order Brute Force Algorithms( Naive Algorithm ) 2018/8/26 Department of Computer Science & Technology

9 Department of Computer Science & Technology
8.1 Brute Force 算法 Brute force: Check for pattern starting at every text position, trying to match any substring of length m in the text with the pattern 。 Analysis of brute force. Running time depends on pattern and text. can be slow when strings repeat themselves Worst case: O(MN) comparisons. too slow when M and N are large 2018/8/26 Department of Computer Science & Technology

10 Department of Computer Science & Technology
Brute Force算法伪代码1 Brute-Force-1 (T,P) ; i =0 ; while i≤n-m do j = 0; //* left to right scan of P while j < m and P[j+1] = T[i+j+1] do j = j+1; if j=m then Report_match_at_position(i-j+1); i = i+1; Return. 2018/8/26 Department of Computer Science & Technology

11 Department of Computer Science & Technology
Brute Force算法伪代码2 Char text[], pat[] ; int n, m ; { int i, j, k, lim ; lim = n-m+1 ; for (i=1 ; i <= lim ; i++) /* search */ k=i ; for (j=1 ; j<=m && text[k]==pat[j]; j++) k++; if (j>m) Report_match_at_position(i-j+1); } 2018/8/26 Department of Computer Science & Technology

12 Brute Force串匹配实例 n e l Search Text d n e d l Search Pattern n e d l
2018/8/26

13 Brute Force串匹配实例 n e l Search Text d n e d l Search Pattern n e
超出右端边界,停止! 2018/8/26

14 Department of Computer Science & Technology
Brute Force算法分析 Analysis of brute force. Running time depends on pattern and text. can be slow when strings repeat themselves Worst case: MN comparisons. too slow when M and N are large b a Search Pattern a Search Text b 2018/8/26 Department of Computer Science & Technology

15 How To Save Comparisons
How to avoid recomputation? Pre-analyze search pattern. Ex: suppose that first 5 characters of pattern are all a's. If T[1..5] matches P[1..5] then T[2..5] matches P[1..4]. no need to check i = 2, j = 1, 2, 3, 4 saves 4 comparisons Need better ideas in general. b a Search Pattern a Search Text b 2018/8/26 Department of Computer Science & Technology

16 Homework 32.1 Page 579 : ,

17 Department of Computer Science & Technology
8.2 KMP算法 KMP算法思想:当遇到一个不成功匹配后,充分利用已经得到的有关前一部分匹配的信息,避免多余的测试,加快匹配过程。 在匹配过程过程中,文本串中的当前指针只会向右移(增加),不会向左倒退; 在测试文本串的 T[i+1..i+m]这一段时,得到一个部分匹配: P[1..j] = T[i+1..i+j], 但 P[j+1] ≠ T[i+j+1]; 设 k 是使得 P[1..k] = P[(j-k+1)..j]的最大整数(即 P[1..j]中最长的与真前缀相同的真后缀的长度) 定义: Next[j+1]= max{ k+1|P[1..k]是P[1..j]的后缀,j>k≥0 } Next 函数值的计算只与模式串有关,与文本串内容无关,可以在进行匹配前预先计算得到 Next[1..m]. 2018/8/26 Department of Computer Science & Technology

18 KMP算法中的Next函数 算法的运行时间为:O (m) Next(P[1..m]) 由于 i - j ≥ 0, 而且 i - j 单调增;
i – j 不变的次数不超过m; 3. i – j ≤ m, 其增加的次数 ≤ m。 Next(P[1..m]) 1. j ← 0; 2. m ← Length(P) ; 3. For i ← 1 to m do Next[i] ← j ; While j > 0 and P[i]≠P[j] do j ← Next[j] ; j ← j + 1; 在《算法导论》一书中定义了另一种类似的函数 π[i], 两种函数之间的关系为: π[i] = Next[i+1] -1 2018/8/26 Department of Computer Science & Technology

19 Department of Computer Science & Technology
KMP算法伪代码 算法运行时间: O (n) 由于 i - j ≥ 0, 而且 i - j 单调增; i – j 不变的次数不超过n; i – j ≤ n, 其增加的次数 ≤ n。 KMP(T, P) 1 j ← 1; 2 For i ← 1 to n do while j > 0 and T[i] ≠ P[j] do j ← Next[j] ; if j = m then // 找到一个成功匹配 return (i-m+1) ; j ← j +1 ; 8 return (none) 2018/8/26 Department of Computer Science & Technology

20 Department of Computer Science & Technology
2018/8/26 Department of Computer Science & Technology

21 Department of Computer Science & Technology
2018/8/26 Department of Computer Science & Technology

22 KMP算法实例 n e Search Text l d Next(P) n e Search Pattern 1 2 3
1. j ← 0; 2. m ← Length(P) ; 3. For i ← 1 to m do Next[i] ← j ; While j > 0 and P[i]≠P[j] do j ← Next[j] ; j ← j + 1; n e Search Pattern 1 2 3 i = 1, j = 0, Next[1] = 0 i = 2, j = 1, Next[2] = 1 i = 3, j = 1, Next[3] = 1 i = 4, j = 1, Next[4] = 1 i = 5, j = 1, Next[5] = 2 i = 6, j = 2, Next[6] = 3 2018/8/26

23 KMP算法实例 n e Search Text l d n e Search Pattern 从文本串T的最左端开始匹配 n e
KMP(T, P) j ← 1; For i ← 1 to n do while j > 0 and T[i] ≠ P[j] do j ← Next[j] ; if j = m then // 找到一个成功匹配 return (i-m+1) ; j ← j +1 ; return (none) n e Search Pattern 1 2 3 2018/8/26

24 KMP算法实例 n e Search Text l d ? n e Search Pattern
j = 1, i = 1, P[1] = T[1], 则: j = j + 1, i = i + 1, 比较 P[j]和T[i] KMP(T, P) j ← 1; For i ← 1 to n do while j > 0 and T[i] ≠ P[j] do j ← Next[j] ; if j = m then // 找到一个成功匹配 return (i-m+1) ; j ← j +1 ; return (none) n e Search Pattern 1 2 3 2018/8/26

25 KMP算法实例 n e Search Text l d n e Search Pattern n e Search Pattern
j = 2, i = 2, P[2] ≠ T[2], 则: j = Next[2], 比较 P[j]和 T[i] KMP(T, P) j ← 1; For i ← 1 to n do while j > 0 and T[i] ≠ P[j] do j ← Next[j] ; if j = m then // 找到一个成功匹配 return (i-m+1) ; j ← j +1 ; return (none) n e Search Pattern 1 2 3 2018/8/26

26 KMP算法实例 n e Search Text l d ? n e Search Pattern
j = 1, i = 2, P[1] = T[2], 则: j = j + 1, i = i+1; 比较 P[2]和 T[3] KMP(T, P) j ← 1; For i ← 1 to n do while j > 0 and T[i] ≠ P[j] do j ← Next[j] ; if j = m then // 找到一个成功匹配 return (i-m+1) ; j ← j +1 ; return (none) n e Search Pattern 1 2 3 2018/8/26

27 KMP算法实例 n e Search Text l d j = 2, i = 3, P[2] = T[3], 则:
j = j + 1, i = i+1; 比较 P[3]和 T[4] ? n e Search Pattern KMP(T, P) j ← 1; For i ← 1 to n do while j > 0 and T[i] ≠ P[j] do j ← Next[j] ; if j = m then // 找到一个成功匹配 return (i-m+1) ; j ← j +1 ; return (none) n e Search Pattern 1 2 3 2018/8/26

28 KMP算法实例 n e Search Text l d j = 3, i = 4, P[3] = T[4], 则:
j = j + 1, i = i+1; 比较 P[4]和 T[5] ? n e Search Pattern KMP(T, P) j ← 1; For i ← 1 to n do while j > 0 and T[i] ≠ P[j] do j ← Next[j] ; if j = m then // 找到一个成功匹配 return (i-m+1) ; j ← j +1 ; return (none) n e Search Pattern 1 2 3 2018/8/26

29 KMP算法实例 n e Search Text l d j = 4, i = 5, P[4] = T[5], 则:
j = j + 1, i = i+1; 比较 P[5]和 T[6] ? n e Search Pattern KMP(T, P) j ← 1; For i ← 1 to n do while j > 0 and T[i] ≠ P[j] do j ← Next[j] ; if j = m then // 找到一个成功匹配 return (i-m+1) ; j ← j +1 ; return (none) n e Search Pattern 1 2 3 2018/8/26

30 KMP算法实例 n e Search Text l d ? j = 5, i = 6, P[5] = T[6], 则:
j = j + 1, i = i+1; 比较 P[6]和 T[7] n e Search Pattern KMP(T, P) j ← 1; For i ← 1 to n do while j > 0 and T[i] ≠ P[j] do j ← Next[j] ; if j = m then // 找到一个成功匹配 return (i-m+1) ; j ← j +1 ; return (none) n e Search Pattern 1 2 3 2018/8/26

31 KMP算法实例 n e Search Text l d j = 6, i = 7, P[6] ≠ T[7], 则:
j = Next[j], 比较 P[3]和 T[7] n e Search Pattern KMP(T, P) j ← 1; For i ← 1 to n do while j > 0 and T[i] ≠ P[j] do j ← Next[j] ; if j = m then // 找到一个成功匹配 return (i-m+1) ; j ← j +1 ; return (none) n e Search Pattern 1 2 3 2018/8/26

32 KMP算法实例 n e Search Text l d ? n e Search Pattern
j = 3, i = 7, P[3] ≠ T[7], 则: j = Next[j], 比较 P[j]和 T[7] KMP(T, P) j ← 1; For i ← 1 to n do while j > 0 and T[i] ≠ P[j] do j ← Next[j] ; if j = m then // 找到一个成功匹配 return (i-m+1) ; j ← j +1 ; return (none) n e Search Pattern 1 2 3 2018/8/26

33 KMP算法实例 n e Search Text l d ? n e Search Pattern
j = 1, i = 7, P[1] ≠ T[7], 则: j = Next[j], 比较 P[j]和 T[8] KMP(T, P) j ← 1; For i ← 1 to n do while j > 0 and T[i] ≠ P[j] do j ← Next[j] ; if j = m then // 找到一个成功匹配 return (i-m+1) ; j ← j +1 ; return (none) n e Search Pattern 1 2 3 2018/8/26

34 KMP算法实例 n e Search Text l d ? j = 1, i = 8, P[1] ≠ T[8], 则:
j = Next[j], 比较 P[1]和 T[9] n e Search Pattern KMP(T, P) j ← 1; For i ← 1 to n do while j > 0 and T[i] ≠ P[j] do j ← Next[j] ; if j = m then // 找到一个成功匹配 return (i-m+1) ; j ← j +1 ; return (none) n e Search Pattern 1 2 3 2018/8/26

35 KMP算法实例 n e Search Text l d ? j = 1, i = 9, P[1] ≠ T[9], 则:
j = Next[j], 比较 P[1]和 T[10] n e Search Pattern KMP(T, P) j ← 1; For i ← 1 to n do while j > 0 and T[i] ≠ P[j] do j ← Next[j] ; if j = m then // 找到一个成功匹配 return (i-m+1) ; j ← j +1 ; return (none) n e Search Pattern 1 2 3 2018/8/26

36 KMP算法实例 n e Search Text l d ? j = 1, i = 10, P[1] = T[10], 则:
Search Pattern KMP(T, P) j ← 1; For i ← 1 to n do while j > 0 and T[i] ≠ P[j] do j ← Next[j] ; if j = m then // 找到一个成功匹配 return (i-m+1) ; j ← j +1 ; return (none) n e Search Pattern 1 2 3 2018/8/26

37 KMP算法实例 n e Search Text l d ? ? j = 2, i = 11, P[2] = T[11], 则:
Search Pattern KMP(T, P) j ← 1; For i ← 1 to n do while j > 0 and T[i] ≠ P[j] do j ← Next[j] ; if j = m then // 找到一个成功匹配 return (i-m+1) ; j ← j +1 ; return (none) n e Search Pattern 1 2 3 2018/8/26

38 KMP算法实例 n e Search Text l d ? j = 3, i = 12, P[3] = T[12], 则:
Search Pattern KMP(T, P) j ← 1; For i ← 1 to n do while j > 0 and T[i] ≠ P[j] do j ← Next[j] ; if j = m then // 找到一个成功匹配 return (i-m+1) ; j ← j +1 ; return (none) n e Search Pattern 1 2 3 2018/8/26

39 KMP算法实例 n e Search Text l d ? j = 4, i = 13, P[4] = T[13], 则:
Search Pattern KMP(T, P) j ← 1; For i ← 1 to n do while j > 0 and T[i] ≠ P[j] do j ← Next[j] ; if j = m then // 找到一个成功匹配 return (i-m+1) ; j ← j +1 ; return (none) n e Search Pattern 1 2 3 2018/8/26

40 KMP算法实例 n e Search Text l d ? j = 5, i = 14, P[5] = T[14], 则:
Search Pattern KMP(T, P) j ← 1; For i ← 1 to n do while j > 0 and T[i] ≠ P[j] do j ← Next[j] ; if j = m then // 找到一个成功匹配 return (i-m+1) ; j ← j +1 ; return (none) n e Search Pattern 1 2 3 2018/8/26

41 KMP算法实例 算法结束! n e Search Text l d j = 6, i = 15, P[6] = T[15], 则:
j = m, 找到匹配,返回 10 n e Search Pattern 算法结束! KMP(T, P) j ← 1; For i ← 1 to n do while j > 0 and T[i] ≠ P[j] do j ← Next[j] ; if j = m then // 找到一个成功匹配 return (i-m+1) ; j ← j +1 ; return (none) n e Search Pattern 1 2 3 2018/8/26

42 Department of Computer Science & Technology
Summary of KMP KMP summary. Build FSA from pattern. Run FSA on text. O(M + N) worst case string search. Good efficiency for patterns and texts with much repetition. binary files graphics formats Less useful for text strings. On-line algorithm. virus scanning Internet spying 2018/8/26 Department of Computer Science & Technology

43 Department of Computer Science & Technology
KMP算法的历史 History of KMP. Inspired by theorem of Cook that says O(M + N) algorithm should be possible. Discovered in 1976 independently by two groups. Knuth-Pratt. Morris was hacker trying to build an editor. annoying problem that you needed a buffer when performing text search Resolved theoretical and practical problems. Surprise when it was discovered. In hindsight, seems like right algorithm. 2018/8/26 Department of Computer Science & Technology

44 Homework 32.4 Page 593 : , ,

45 Department of Computer Science & Technology
8.3 Shift-Or 算法 uses bitwise techniques; efficient if the pattern length is no longer than the memory-word size of the machine; preprocessing phase in O(m +σ) time and space complexity; searching phase in O(n) time complexity (independent from the alphabet size σ and the pattern length); adapts easily to approximate string matching. 2018/8/26 Department of Computer Science & Technology

46 注意:有的书上算法中所用数组下标从0开始,不是从1开始 !
Shift-Or算法思想 Let R be a bit array of size m. Vector Rj is the value of the array R after text character T[j] has been processed (见下页的图). It contains informations about all matches of prefixes of P that end at position j in the text for 1 < i ≤  m: 注意:有的书上算法中所用数组下标从0开始,不是从1开始 ! 2018/8/26 Department of Computer Science & Technology

47 Department of Computer Science & Technology
Shift-Or算法思想(续) j T P[1] 1 i = 1 P[1..2] i = 2 i = 3 P[1..3] P[1..m]] i = m Rj 2018/8/26 Department of Computer Science & Technology

48 Department of Computer Science & Technology
Shift-Or算法思想(续) The vector Rj+1 can be computed after Rj as follows. For each Rj[i]=0: and If Rj+1[m]=0 then a complete match can be reported. The transition from Rj to Rj+1 can be computed in two steps. 2018/8/26 Department of Computer Science & Technology

49 Department of Computer Science & Technology
Shift-Or算法思想(续) Step 1: For each c in ∑, let Sc be a bit array of size m such that: for 1≤ i < m, Sc[i]=0 iff P[i]=c. 例如: ∑={a, b, c, d} be the alphabet, and ababc the pattern 则: Sa[5..1] = (11010)2, Sb[5..1] = (10101)2, Sc[5..1] = (01111)2, Sd[5..1] = (11111)2. The array Sc denotes the positions of the character c in the pattern P. Each Sc can be preprocessed before the search. 2018/8/26 Department of Computer Science & Technology

50 Department of Computer Science & Technology
Shift-Or算法思想(续) Step 2: The computation of Rj+1 reduces to two operations, shift and or: Rj+1= SHIFT( R j ) OR ST[j+1] Assuming that the pattern length is no longer than the memory-word size of the machine, the space and time complexity of the preprocessing phase is O(m+σ). The time complexity of the searching phase is O(n), thus independent from the alphabet size and the pattern length. 2018/8/26 Department of Computer Science & Technology

51 Department of Computer Science & Technology
Shift-Or算法伪代码 m为模式串长度; P[1..m]为模式串; ASIZE为字符集大小;每个字符c所对应的Sc的存放在数组S[1..ASIZE]中 PreSo( P, m, S ) j←(00000…001)2; lim←(00000…000)2; //二进制数, 位数为模式串长度 m for i←1 to ASIZE do S[i]←(11111…111)2 ; // 二进制数, 位数为模式 m, 全为 1 for i←1 to m do S[ P[i] ]←S[ P[i] ] & (~j); //&, |, ~, <<, >> 为二进制数位运算符 lim←lim | j; //& 按位与; | 按位或; ~按位取反 j←j<<1; // <<左移 >>右移 lim ← ~ (lim>>1); return lim; 2018/8/26 Department of Computer Science & Technology

52 Department of Computer Science & Technology
Shift-Or算法伪代码(续) m为模式串长度; x[1..m]为模式串; n为文本串长度; y[1..n]为文本串;每个字符c所对应的Sc的存放在数组S[1..ASIZE]中 SO (P, m, T, n) state←(11111…111)2; lim←(00000…000)2 lim←PreSo( P, m, S ); for j←1 to n do state←(state<<1) | S[ T[j] ]; //Shift-Or if (state < lim) //找到一个匹配 then OUTPUT( j - m + 1); 2018/8/26 Department of Computer Science & Technology

53 Example For Shift-Or Algorithm
P = “GCAGAGAG” , T = “GCATCGCAGAGAGTATACAGTACG” As R13[8]= 0 it means that an occurrence of P has been found at position 13-8+1=6. 2018/8/26 Department of Computer Science & Technology

54 Example For Shift-Or Algorithm(Cont)
Pattern: ababc, State= 11111;lim =10000 Text: a b d a b a b c Sx[5..1]: State: For example, the state means that in the current position we have two partial matches to the left, of lengths two and four, respectively. The match at the end of the text is indicated by the value 0 in the leftmost bit of the last state of the search. 2018/8/26 Department of Computer Science & Technology

55 Department of Computer Science & Technology
Shift-Or算法 C 代码 int preSo(char *x, int m, unsigned int S[ ]) { unsigned int j, lim; int i; for (i = 0; i < ASIZE; ++i) S[i] = ~0; for (lim = i = 0, j = 1; i < m; ++i, j <<= 1) { S[x[i]] &= ~j; lim |= j; } lim = ~(lim>>1); return (lim); 2018/8/26 Department of Computer Science & Technology

56 Department of Computer Science & Technology
Shift-Or算法 C 代码(续) void SO(char *x, int m, char *y, int n) { unsigned int lim, state; unsigned int S[ASIZE]; int j; if (m > WORD) error("SO: Use pattern size <= word size"); /* Preprocessing */ lim = preSo(x, m, S); /* Searching */ for (state = ~0, j = 0; j < n; ++j) { state = (state<<1) | S[y[j]]; if (state < lim) OUTPUT(j - m + 1); } 2018/8/26 Department of Computer Science & Technology

57 Shift-Or Algorithm 参考文献
BAEZA-YATES, R.A., GONNET, G.H., 1992, A new approach to text searching, Communications of the ACM . 35(10):74-82. BAEZA-YATES R., NAVARRO G., RIBEIRO-NETO B., 1999, Indexing and Searching, in Modern Information Retrieval, Chapter 8, pp , Addison-Wesley. CROCHEMORE, M., LECROQ, T., 1996, Pattern matching and text compression algorithms, in CRC Computer Science and Engineering Handbook, A. Tucker ed., Chapter 8, pp , CRC Press Inc., Boca Raton, FL. WU, S., MANBER, U., 1992, Fast text searching allowing errors, Commun. ACM. 35(10):83-91. 2018/8/26 Department of Computer Science & Technology

58 8.4 The Boyer-Moore Algorithm
The Boyer-Moore algorithm is considered as the most efficient string-matching algorithm in usual applications. A simplified version of it or the entire algorithm is often implemented in text editors for the «search» and «substitute» commands. The algorithm scans the characters of the pattern from right to left beginning with the rightmost one. find offset i in text by moving left to right. compare pattern to text by moving right to left. 2018/8/26 Department of Computer Science & Technology

59 Department of Computer Science & Technology
Boyer-Moore算法介绍 In case of a mismatch (or a complete match of the whole pattern) it uses two precomputed functions to shift the window to the right Shift method : two shift functions called the good-suffix shift (also called matching shift) and the bad-character shift (also called the occurrence shift). match heuristic: compute the Gs table for the pattern effective with small alphabets different rules lead to different worst-case behavior occurrence heuristic: compute the Bc table for the pattern upon mismatch of text character c, look up j = index[c] increase offset i so that jth character of pattern lines up with text character c 2018/8/26 Department of Computer Science & Technology

60 Department of Computer Science & Technology
Good-suffix shift i+j-1 b u T [1..n] a c P [1..m] j shift A mismatch occurs between the character P[i]=a of the pattern and the character T[i+j-1]=b of the text during an attempt at position j. then P[i+1 .. m]= T[i+j .. j+m-1]= u and P[i] ≠ T[i+j-1]. The good-suffix shift consists in aligning the segment P[i+1 .. m] = T[i+j .. j+m-1] with its rightmost occurrence in P that is preceded by a character different from P[i] Match shift: (good-suffix shift) 2018/8/26 Department of Computer Science & Technology

61 Good-suffix shift (cont.)
If there exists no such segment, the shift consists in aligning the longest suffix v of T[i+j+1 .. j+m-1] with a matching prefix of P. v P [1..m] a u i+j-1 b T [1..n] j shift Match shift: (good-suffix shift) 2018/8/26 Department of Computer Science & Technology

62 Department of Computer Science & Technology
Bad-character shift Occurrence shift: The bad-character shift consists in aligning the text character T[i+j-1] with its rightmost occurrence in P[1 .. m-1]. i+j-1 b u T [1..n] a P [1..m] j shift contains no b 2018/8/26 Department of Computer Science & Technology

63 Bad-character shift (cont.)
Occurrence shift: If T[i+j-1] does not occur in the pattern P, no occurrence of P in T can include T[i+j-1], and the left end of the window is aligned with the character immediately after T[i+j-1], namely T[i+j]. P [1..m] i+j-1 b u T [1..n] a j shift contains no b 2018/8/26 Department of Computer Science & Technology

64 Perform the Maximal Shift
Since the Occurrence shift(bad-character shift) can be negative, thus for shifting the window, the Boyer-Moore algorithm applies the maximum between the good-suffix shift and bad-character shift. Both shifts are pre-computed; The good-suffix shift function is stored in a table Gs of size m+1. The bad-character shift function is stored in a table Bc of size σ. 2018/8/26 Department of Computer Science & Technology

65 Good-suffix shift function
To compute the table Gs of size m+1, we define two conditions: Cond-1 (i, s): for each k such that i < k ≤ m, s > k or P[k-s]=P[k] ; Cond-2 (i, s): if s <i then P[i-s] ≠ P[i]. //*mismatch property// For 1≤ j ≤ m, defign: Gs[i+1]=min {s>0 :  Cond-1 (i, s) and Cond-2(i, s) hold} define Gs[1] as the length of the period of P: Gs[1] = m - Bord[m]; Bord[m] = max{k: P[1..k] = P[m- k+1..m]} 实际上, Bord[m] 即为模式串 P 的最长的相同真前缀、真后缀的长度! 2018/8/26 Department of Computer Science & Technology

66 Good-suffix shift Computation
The computation of the table Gs use a table suff defined as follows: for 1≤i≤m, Suff[i]=max{k : P[i-k+1.. i]=P[m-k+1.. m]} Suffixes (P, m, Suff) Suff [m] ← m; g ←m; for i←m-1 downto 1 do if (i > g && Suff[i + m - f] < i - g) then Suff[i] ←Suff[i + m - f]; else do if( i<g) then g ← i; f ← i; while(g >= 1 && P[g] == P[g + m - f] ) g--; Suff[i] ← f - g; 2018/8/26 Department of Computer Science & Technology

67 Good-suffix shift Computation
Pre-Gs (P, m, Gs) suffixes(P, m, Suff); for i←1 to m do Gs[i] ← m; j←1; for i←m downto 0 do if (i == 0 || Suff[i] == i ) then while( j <= m – i ) do if (Gs[j] == m) then Gs[j] ← m - i; j++; for i←1 to m – 1 do Gs[ m - Suff[i] ] ← m - i; 2018/8/26 Department of Computer Science & Technology

68 Bad-character shift function
The bad-character shift function is stored in a table Bc of size : Pre-Bc (P, m, Bc) for i←1 to ASIZE do Bc[i] ← m; for i←1 to m-1 do Bc[ P[i] ] = m - i; 2018/8/26 Department of Computer Science & Technology

69 Boyer-Moore Algorithm Pseudocode
BM(P, m, T , n) Pre-Gs(P, m, Gs); Pre-Bc(P, m, Bc); j←1; while (j ≤ n - m + 1 ) do for i← m downto 1 do if ( P[i] == T[i + j - 1] ) then i--; if (i < 1) then OUTPUT(j); j ← j + Gs[1]; else j ← j + MAX( Gs[i], Bc[ T[i + j -1] ] - m + i ); 2018/8/26 Department of Computer Science & Technology

70 Example for BM Algorithm
P [1..8] = GCAGAGAG  T [1..24]= GCATCGCAGAGAGTATACAGTACG Gs[i+1]=min {s>0 :  Cond-1 (i, s) and Cond-2(i, s) hold} Gs[1] = m - Bord[m]; Suff[i]=max{k : P[i-k+1.. i]=P[m-k+1.. m]} Cond-1 (i, s): for each k such that i < k ≤ m, s > k or P[k-s]=P[k] ; Cond-2 (i, s): if s <i then P[i-s] ≠ P[i]. //*mismatch property// 2018/8/26 Department of Computer Science & Technology

71 Example for BM Algorithm
The Boyer-Moore algorithm performs 17 character comparisons on the example. 2018/8/26 Department of Computer Science & Technology

72 Boyer-Moore Algorithm Analysis
Tables Bc and Gs can be precomputed in time O(m+σ) before the searching phase and require an extra-space in O(m+σ). The searching phase time complexity is quadratic but at most 3n text character comparisons are performed when searching for a non periodic pattern. On large alphabets (relatively to the length of the pattern) the algorithm is extremely fast. When searching for am-1b in bn the algorithm makes only O(n/m) comparisons, which is the absolute minimum for any string-matching algorithm in the model where the pattern only is preprocessed. 2018/8/26 Department of Computer Science & Technology

73 Boyer-Moore Algorithm Analysis
BM algorithm makes O(n) comparisons to find the first occurrence of a pattern in a test of length n. O(N / M) average case if given letter usually doesn't occur in string. English text: 10 character search string, 26 char alphabet time decreases as pattern length increases sublinear in input size! O(M + N) worst-case with Galil variant. proof is quite difficult 2018/8/26 Department of Computer Science & Technology

74 References for BM Algorithm
AHO, A.V., 1990, Algorithms for finding patterns in strings. in Handbook of Theoretical Computer Science, Volume A, Algorithms and complexity, J. van Leeuwen ed., Chapter 5, pp , Elsevier, Amsterdam. AOE, J.-I., 1994, Computer algorithms: string pattern matching strategies, IEEE Computer Society Press. BAASE, S., VAN GELDER, A., 1999, Computer Algorithms: Introduction to Design and Analysis, 3rd Edition, Chapter 11, Addison-Wesley Publishing Company. BAEZA-YATES R., NAVARRO G., RIBEIRO-NETO B., 1999, Indexing and Searching, in Modern Information Retrieval, Chapter 8, pp , Addison-Wesley. BEAUQUIER, D., BERSTEL, J., CHRÉTIENNE, P., 1992, Éléments d'algorithmique, Chapter 10, pp , Masson, Paris. BOYER R.S., MOORE J.S., 1977, A fast string searching algorithm. Communications of the ACM. 20: COLE, R., 1994, Tight bounds on the complexity of the Boyer-Moore pattern matching algorithm, SIAM Journal on Computing 23(5): CORMEN, T.H., LEISERSON, C.E., RIVEST, R.L., Introduction to Algorithms, Chapter 34, pp , MIT Press. 2018/8/26 Department of Computer Science & Technology

75 References for BM Algorithm
CROCHEMORE, M., Off-line serial exact string searching, in Pattern Matching Algorithms, ed. A. Apostolico and Z. Galil, Chapter 1, pp 1-53, Oxford University Press. CROCHEMORE, M., HANCART, C., 1999, Pattern Matching in Strings, in Algorithms and Theory of Computation Handbook, M.J. Atallah ed., Chapter 11, pp , CRC Press Inc., Boca Raton, FL. CROCHEMORE, M., LECROQ, T., 1996, Pattern matching and text compression algorithms, in CRC Computer Science and Engineering Handbook, A. Tucker ed., Chapter 8, pp , CRC Press Inc., Boca Raton, FL. CROCHEMORE, M., RYTTER, W., 1994, Text Algorithms, Oxford University Press. GONNET, G.H., BAEZA-YATES, R.A., Handbook of Algorithms and Data Structures in Pascal and C, 2nd Edition, Chapter 7, pp , Addison-Wesley Publishing Company. GOODRICH, M.T., TAMASSIA, R., 1998, Data Structures and Algorithms in JAVA, Chapter 11, pp , John Wiley & Sons. GUSFIELD, D., 1997, Algorithms on strings, trees, and sequences: Computer Science and Computational Biology, Cambridge University Press. 2018/8/26 Department of Computer Science & Technology

76 References for BM Algorithm
HANCART, C., Analyse exacte et en moyenne d'algorithmes de recherche d'un motif dans un texte, Ph. D. Thesis, University Paris 7, France. KNUTH, D.E., MORRIS (Jr) J.H., PRATT, V.R., 1977, Fast pattern matching in strings, SIAM Journal on Computing 6(1): LECROQ, T., 1992, Recherches de mot, Ph. D. Thesis, University of Orléans, France. LECROQ, T., 1995, Experimental results on string matching algorithms, Software - Practice & Experience 25(7): SEDGEWICK, R., 1988, Algorithms, Chapter 19, pp , Addison-Wesley Publishing Company. SEDGEWICK, R., 1988, Algorithms in C, Chapter 19, Addison-Wesley Publishing Company. STEPHEN, G.A., 1994, String Searching Algorithms, World Scientific. WATSON, B.W., 1995, Taxonomies and Toolkits of Regular Language Algorithms, Ph. D. Thesis, Eindhoven University of Technology, The Netherlands. WIRTH, N., 1986, Algorithms & Data Structures, Chapter 1, pp , Prentice-Hall. Maxime C.,Wojciech R., Jewels of Stringlogy—Text Algorithms, 2003, World Scientific. 2018/8/26 Department of Computer Science & Technology

77 8.5 The Boyer-Moore-Horspool Algorithm
A simplification of BM Algorithm. The bad-character shift used in the Boyer-Moore algorithm (see chapter Boyer-Moore algorithm) is not very efficient for small alphabets, but when the alphabet is large compared with the length of the pattern, as it is often the case with the ASCII table and ordinary searches made under a text editor, it becomes very useful. Using it alone produces a very efficient algorithm in practice. Horspool proposed to use only the bad-character shift of the rightmost character of the window to compute the shifts in the Boyer-Moore algorithm. 2018/8/26 Department of Computer Science & Technology

78 Horspool Algorithm Pseudocode
void HORSPOOL(char *x, int m, char *y, int n) { int j, Bc[ASIZE]; char c; Pre-Bc(P, m, Bc); //* Preprocessing *// j = 1; while ( j ≤ n – m +1) { c = T[ j + m-1 ]; if ( P[m ] == c && memcmp( P, T +j-1, m ) == 0) OUTPUT( j ); j += Bc[c]; } 2018/8/26 Department of Computer Science & Technology

79 Horspool Algorithm Pseudocode
HORSPOOL(P[1..m], T[1.. n] ) Pre-Bc (P, m, Bc); //* Preprocessing *// i = m; while i≤n do k = //* 匹配字符的数目*// while ( k ≤ m ) and P[m-k+1] = T[i-k+1] do k=k+1; if k=m then OUTPUT( i-m+1 ); else i=i + Bc[T[i]]; Return 有的书上采用这种算法描述,这与前面的描述在字符比较次序上有所不同。 2018/8/26 Department of Computer Science & Technology

80 Example for Horspool Algorithm
P[1..8] = GCAGAGAG  T[1..24]= GCATCGCAGAGAGTATACAGTACG bmBc table used by Horspool algorithm The Horspool algorithm performs 17 character comparisons on the example. 2018/8/26 Department of Computer Science & Technology

81 Example for Horspool Algorithm
Eaxmple : T : x y z a b r a x y z a b r a c a d a b r a P : a b r a c a d a b r a c : Bc[c] : 3 2 6 4 1 11 a b c d r x y z 2018/8/26 Department of Computer Science & Technology

82 The Boyer-Moore-Horspool Algorithm(cont.)
x y z a b r Search Text c d a b r c d Bc[a] =3 a b r c d Bc[a] =3 a b r c d Bc[d] =4 a b r c d found 2018/8/26 Department of Computer Science & Technology

83 Horspool Algorithm Analysis
Easy to implement; Preprocessing phase in O(m+σ) time and O(σ) space complexity; Searching phase in O(mn) time complexity; The average number of comparisons for one text character is between 1/σand 2/(σ+1). 2018/8/26 Department of Computer Science & Technology

84 References for Horspool Algorithm
AHO, A.V., 1990, Algorithms for finding patterns in strings. in Handbook of Theoretical Computer Science, Volume A, Algorithms and complexity, J. van Leeuwen ed., Chapter 5, pp , Elsevier, Amsterdam. BAEZA-YATES, R.A., RÉGNIER, M., 1992, Average running time of the Boyer-Moore-Horspool algorithm, Theoretical Computer Science 92(1):19-31. BEAUQUIER, D., BERSTEL, J., CHRÉTIENNE, P., 1992, Éléments d'algorithmique, Chapter 10, pp , Masson, Paris. CROCHEMORE, M., HANCART, C., 1999, Pattern Matching in Strings, in Algorithms and Theory of Computation Handbook, M.J. Atallah ed., Chapter 11, pp , CRC Press Inc., Boca Raton, FL. HANCART, C., Analyse exacte et en moyenne d'algorithmes de recherche d'un motif dans un texte, Ph. D. Thesis, University Paris 7, France. HORSPOOL R.N., 1980, Practical fast searching in strings, Software - Practice & Experience, 10(6): LECROQ, T., 1995, Experimental results on string matching algorithms, Software - Practice & Experience 25(7): STEPHEN, G.A., 1994, String Searching Algorithms, World Scientific. 2018/8/26 Department of Computer Science & Technology

85 8.6 The Quick Search algorithm
The Quick Search algorithm uses only the bad-character shift table (see Boyer-Moore algorithm). After an attempt where the window is positioned on the text factor T [j .. j+m-1], the length of the shift is at least equal to one. So, the character T [j+m] is necessarily involved in the next attempt, and thus can be used for the bad-character shift of the current attempt. The bad-character shift of the present algorithm is slightly modified to take into account the last character of P as follows: for c in ∑: Qs-Bc[c]=min{i : 1≤ i ≤ m and P[m+1-i]=c} if c occurs in x, m+1 otherwise. 2018/8/26 Department of Computer Science & Technology

86 Bad-character shift function
Pre-Bc (P, m, Qs-Bc) for i←1 to ASIZE do Qs-Bc[i] ← m+1; for i←1 to m do Qs-Bc[ P[i] ] = m+1 - i; 2018/8/26 Department of Computer Science & Technology

87 Quick Search algorithm Pseudocode
void QS(char *P, int m, char *T, int n) { int j, Qs-Bc[ASIZE]; Pre-Bc(P, m, Qs-Bc); //* Preprocessing *// //* Searching *// j = 1; while (j ≤ n – m+1) { if (memcmp(P, T+ j -1, m) == 0) //*P,T下标从1开始*// OUTPUT( j ); j = j+ Qs-Bc[ T[ j + m] ]; //* shift *// } 2018/8/26 Department of Computer Science & Technology

88 Example of Quick Search algorithm
P = GCAGAGAG a A C G T Qs-Bc[a] Qs-Bc table The Quick Search algorithm performs 15 character comparisons on the example. 2018/8/26 Department of Computer Science & Technology

89 Example of Quick Search algorithm
Eaxmple : T : x y z a b r a x y z a b r a c a d a b r a P : a b r a c a d a b r a c : Qs-Bc[c] : 1 3 7 5 2 12 a b c d r x y z 2018/8/26 Department of Computer Science & Technology

90 Quick Search Algorithm(cont.)
x y z a b r Search Text c d a b r c d Bc[b] =3 a b r c d z Bc[c] =7 a b r c d found 2018/8/26 Department of Computer Science & Technology

91 Quick Search algorithm Analysis
Simplification of the Boyer-Moore algorithm, Uses only the bad-character shift; Easy to implement; Preprocessing phase in O(m+σ) time and O(σ) space complexity; Searching phase in O(mn) time complexity; During the searching phase the comparisons between pattern and text characters during each attempt can be done in any order. The searching phase has a quadratic worst case time complexity but it has a good practical behaviour. Very fast in practice for short patterns and large alphabets. 2018/8/26 Department of Computer Science & Technology

92 References for Quick Search
CROCHEMORE, M., LECROQ, T., 1996, Pattern matching and text compression algorithms, in CRC Computer Science and Engineering Handbook, A. Tucker ed., Chapter 8, pp , CRC Press Inc., Boca Raton, FL. LECROQ, T., 1995, Experimental results on string matching algorithms, Software - Practice & Experience 25(7): STEPHEN, G.A., 1994, String Searching Algorithms, World Scientific. SUNDAY D.M., 1990, A very fast substring search algorithm, Communications of the ACM . 33(8): 2018/8/26 Department of Computer Science & Technology

93 Department of Computer Science & Technology
Homework 已知: T [1…30]=ACGCTDAGAAGDCAGADGTDAGCDGDAGC. P [1..10]=DAGCDGDAGC 计算Shift Or算法中的Sc数组(S[T(i)])t和R数组(state)变换的情况( 给出表格), 给出BM算法中的 Bc、Gs、Suff 数组,计算BM算法找到第1个成功匹配所需的字符比较次数; 给出QS算法中的 Qs-Bc数组,计算QS算法找到第1个成功匹配所需的字符比较次数; 2018/8/26 Department of Computer Science & Technology

94 8.7 The Karp-Rabin Algorithm
Hashing provides a simple method to avoid a quadratic number of character comparisons in most practical situations. Instead of checking at each position of the text if the pattern occurs, it seems to be more efficient to check only if the contents of the window “looks like” the pattern. Computing the signature function of each possible m-character substring Check if it is equal to the signature function of the pattern If an equality is found, it is still necessary to check the equality P[1..m] = T [j .. j+m-1] character by character. 2018/8/26 Department of Computer Science & Technology

95 The Karp-Rabin Algorithm
Signature function h(k)= k mod q, q is a large prime An hashing function hash should have the following properties: Efficiently computable Highly discriminating(有差别) for strings hash(T[j+1 .. j+m]) must be easily computable from hash( T [j.. j+m-1]) and T [j+m] hash(T[j+1 .. j+m])= rehash (T [j], T [j+m], hash (T [j .. j+m-1]) 2018/8/26 Department of Computer Science & Technology

96 The Karp-Rabin Algorithm
Let d = |∑|, define a function ord : ∑→{0,1,2,…,d-1} For a word w of length m let hash(w) be defined as follows: Let: x[i]=ord( w[i] ), 1≤ i ≤ m hash(w[1 .. m]) =(x[1]*dm-1+ x[2]*dm-2+···+ x[m]*d0) mod q where q is a large number, hash(w[1 .. m]) is an integer. hash(w[2 ..m+1])=(x[2]*dm-1+x[3]*dm-2+···+x[m+1]*d0) mod q = ( (hash(w[1 .. m])-x[1]*dm-1)*d+ x[m+1]*d0) mod q rehash(a, b, h)= ( (h-a*dm-1)*d+b ) mod q 其中 dm-1 mod 可以预先计算,将其记为 y . d 可以是以2为底,也可以8,10或者素数为底 2018/8/26 Department of Computer Science & Technology

97 Karp-Rabin Algorithm Pseudocode
KR(P, m, T , n) y ← 1; Phash ←0; Thash ←0; for i←1 to m-1 do y ← y*d; //* 计算 y = d m-1 for i←1 to m do Phash ←( (Phash*d) + ord( P[i] ) ); Thash ←( (Thash*d) + ord( T[i] ) ); j←1; while (j ≤ n-m+1) if (Phash == Thash && memcmp(P, T + j -1, m) == 0) then OUTPUT( j ); Thash ←(Thash - ord( T[j] )*y) *d + ord( T[ j+m ] ) ; j ++; 2018/8/26 Department of Computer Science & Technology

98 The Karp-Rabin Algorithm (cont.)
KR(P, m, T , n) d←1; Phash ←0; Thash ←0; for i←1 to m-1 do d ← d<<1; // <<1相当于乘2 d = 2m-1 for i←1 to m do Phash ←((Phash<<1) + P[i]); Thash ←((Thash<<1) + T[i]); j←1; while (j ≤n-m+1) if (Phash == Thash && memcmp(P, T + j -1, m) == 0) then OUTPUT(j); Thash ←(Thash - T[j]*d) << 1 + T[j+m] ; j++; d =2 时 KR算法伪代码 2018/8/26 Department of Computer Science & Technology

99 The Karp-Rabin Algorithm (cont.)
P= “GCAGAGAG” , T= “GCATCGCAGAGAGTATACAGTACG” hash [P]=17597 G C A T Search Text G C A hash( T [1 .. 8]) = 17819 G C A hash( T [2 .. 9]) = 17533 G C A hash( T [ ]) = 17979 2018/8/26 Department of Computer Science & Technology

100 The Karp-Rabin Algorithm (cont.)
Search Text G C A hash( T [ ]) = 19389 G C A hash( T [ ]) = 17339 G C A hash( T [ ]) = found G C A hash( T [ ]) = 17102 G C A …… hash( T [ ]) = 17102 2018/8/26 Department of Computer Science & Technology

101 Karp-Rabin Algorithm Analysis
The preprocessing phase of the Karp-Rabin algorithm consists in computing hash(P). It can be done in constant space and O(m) time. During searching phase, it is enough to compare hash(P) with hash(T[j .. j+m-1]) for 1≤ j ≤ n–m+1. If an equality is found, it is still necessary to check the equality P=T[j .. j+m-1] character by character. The time complexity of the searching phase of the Karp-Rabin algorithm is O(mn) (when searching for am in an for instance). Its expected number of text character comparisons is O(n+m). 2018/8/26 Department of Computer Science & Technology

102 References for Karp-Rabin Algorithm
AHO, A.V., 1990, Algorithms for finding patterns in strings. in Handbook of Theoretical Computer Science, Volume A, Algorithms and complexity, J. van Leeuwen ed., Chapter 5, pp , Elsevier, Amsterdam. CORMEN, T.H., LEISERSON, C.E., RIVEST, R.L., Introduction to Algorithms, Chapter 34, pp , MIT Press. CROCHEMORE, M., HANCART, C., 1999, Pattern Matching in Strings, in Algorithms and Theory of Computation Handbook, M.J. Atallah ed., Chapter 11, pp , CRC Press Inc., Boca Raton, FL. GONNET, G.H., BAEZA-YATES, R.A., Handbook of Algorithms and Data Structures in Pascal and C, 2nd Edition, Chapter 7, pp , Addison-Wesley Publishing Company. HANCART, C., Analyse exacte et en moyenne d'algorithmes de recherche d'un motif dans un texte, Ph. D. Thesis, University Paris 7, France. 2018/8/26 Department of Computer Science & Technology

103 References for Karp-Rabin Algorithm
CROCHEMORE, M., LECROQ, T., 1996, Pattern matching and text compression algorithms, in CRC Computer Science and Engineering Handbook, A. Tucker ed., Chapter 8, pp , CRC Press Inc., Boca Raton, FL. KARP R.M., RABIN M.O., 1987, Efficient randomized pattern-matching algorithms. IBM J. Res. Dev. 31(2): SEDGEWICK, R., 1988, Algorithms, Chapter 19, pp , Addison-Wesley Publishing Company. SEDGEWICK, R., 1988, Algorithms in C, Chapter 19, Addison-Wesley Publishing Company. STEPHEN, G.A., 1994, String Searching Algorithms, World Scientific. 2018/8/26 Department of Computer Science & Technology

104 Homework 32.2 Page 583 : ,

105 Department of Computer Science & Technology
Conclusions Test: Random pattern, random text and English text Best: The Boyer-Moore-Horspool Algorithm Drawback: preprocessing time and space(depend on alphabet/pattern size) Small pattern: The Shift-Or Algorithm Large alphabet: The Knuth-Morris-Pratt Algorithm Others: The Boyer-Moore Algorithm “don’t care”: The Shift-Or Algorithm 2018/8/26 Department of Computer Science & Technology

106 Thank you ! 2018/8/26 计算机科学与技术系


Download ppt "算法基础 第八讲:串匹配算法 主 讲: 顾 乃 杰 教授 单 位: 计算机科学技术学院 学 期: (秋)"

Similar presentations


Ads by Google