【算法与数据结构】字符串匹配之KMP算法

 

 1 // KMP.cpp : 定义控制台应用程序的入口点。
 2 //
 3 
 4 #include "stdafx.h"
 5 #include <iostream>
 6 #include <new>
 7 using namespace std;
 8 
 9 /************************************************************************
10    这个算法的关键在于不用回溯指示主串当前比较位置的变量i,
11    当主串和模式串失配时,只需要将模式串向右滑动尽可能大的距离
12    即决定主串当前位置i上的元素 应该和 模式串的哪个元素比较
13    即关键在于求的一个next[j]数组,当主串在i位置和模式串的j位置失配时,
14    应该将模式串的next[j]位置元素和主串i位置元素开始比较,重复此过程
15 
16    所以问题的关键在于求解一个next[j]数组,这个数组的求解是和主串无关的。
17 
18 ************************************************************************/
19 
20 //以下代码并没有完全的对参数进行检查
21 
22 //求解next数组
23 //lpString为模式串
24 //next为输入数组
25 void GetNext(const TCHAR* lpString, int* next)
26 {
27     if (NULL == lpString || NULL == next){ return; }
28     int j = 0;
29     int k = 0;
30     next[0] = -1;
31     j = 0;
32     k = -1;
33 
34     int length = _tcslen(lpString);
35     while (j < length - 1)
36     {
37         if (-1 == k || lpString[j] == lpString[k])
38         {
39             ++j;
40             ++k;
41             next[j] = k;
42         }
43         else
44         {
45             k = next[k];
46         }        
47     }    
48 }
49 
50 
51 int KMPMatch(const TCHAR* lpMain, const TCHAR* lpMatch)
52 {
53     int nMain = _tcslen(lpMain);
54     int nMatch = _tcslen(lpMatch);
55     int* pNext = new int[nMatch]();
56     int i = 0;
57     int j = 0;
58 
59     if (NULL == pNext)
60     {
61         return -1;
62     }
63 
64     GetNext(lpMatch, pNext);
65     while (i < nMain && j < nMatch)
66     {
67         if (-1 == j || lpMain[i] == lpMatch[j])
68         {
69             ++i; ++j;
70         }
71         else
72         {
73             j = pNext[j];
74         }                
75     }
76 
77     delete[] pNext;
78     pNext = NULL;
79 
80     if (j >= nMatch)
81     {
82         return i - nMatch;
83     }
84 
85     return -1;
86 }
87 
88 int _tmain(int argc, _TCHAR* argv[])
89 {
90     const TCHAR* lpMain = _T("helloworld");
91     const TCHAR* lpMatch = _T("oworl");
92 
93     wcout<<"模式串 "<<lpMatch<<" 在主串 "<<lpMain<<" 中的位置为 " \
94         <<KMPMatch(lpMain, lpMatch)<<endl;;
95 
96     return 0;
97 }

 

执行结果如下:

 

 

 

 

posted on 2014-04-22 14:07  崔好好  阅读(185)  评论(0编辑  收藏  举报

导航