字符串匹配算法之————KMP算法

上一篇中讲到暴力法字符串匹配算法,但是暴力法明显存在这样一个问题:一次只移动一个字符。但实际上,针对不同的匹配情况,每次移动的间隔可以更大,没有必要每次只是移动一位:

关于KMP算法的描述,推荐一篇博客:https://blog.csdn.net/weixin_36604953/article/details/78576637

该博客详细的描述了KMP算法原理。下面的代码实现了KMP算法:

 1 //使用暴力穷举法, KMP算法完成字符串匹配算法 
 2 # include "iostream"
 3 #include"string"
 4 #include"vector"
 5 using namespace std;
 6 vector<int>& BFmatch(string & , string & , vector<int>&);
 7 vector<int>& KMPStrMatch(string &, string &, vector<int>&);
 8 void ShowPos(vector<int>& );
 9 int main()
10 {
11     string ModelStr, SonStr;
12     vector<int> pos;
13     cout << "请输入待匹配字符串:";
14     cin >> ModelStr ;
15     cout << endl;
16     cout << "请输入子字符串:";
17     cin >> SonStr;
18     cout << endl;
19     //BFmatch(ModelStr, SonStr, pos);
20     KMPStrMatch(ModelStr, SonStr, pos);
21     ShowPos(pos);
22     system("pause");
23 }
24 vector<int>& BFmatch(string & ModelStr, string & SonStr,vector<int>& pos)
25 {
26     for (int i = 0; i < ModelStr.size(); i++)
27     {
28         int k = 0;
29         for (int j = i; k < SonStr.size(); j++, k++)
30         {
31             if (SonStr[k] == ModelStr[j])
32                 continue;
33             else
34                 break;
35         }
36         if (k == SonStr.size())
37             pos.push_back(i);
38     }
39     return pos;
40 }
41 void ShowPos(vector<int>& pos)
42 {
43     if (pos.size() != 0)
44     {
45         cout << "the first position of MatchingStr:";
46         for (int i = 0; i < pos.size(); i++)
47         {
48             cout << pos[i] << "\t";
49         }
50         cout << endl;
51     }
52     else
53         cout << "no such string!" << endl;
54 }
55 vector<int>& KMPStrMatch(string & ModelStr, string & SonStr, vector<int>& pos)
56 {
57     string ComStr;
58     string tmp1, tmp2;
59     int j = 0, i = 0, len = 0;;
60     while(j< (ModelStr.size()- SonStr.size()+1))
61     {
62         if (ModelStr[j] != SonStr[0])
63         {
64             j++;
65             continue;//首位不匹配直接加1
66         }
67         else
68         {
69             while ((j< ModelStr.size())&&(ModelStr[j] == SonStr[i]))//&&前面的约束条件保证了不会发生内存越界
70             {
71                 j++;
72                 i++;
73             }
74             if (i == SonStr.size())
75                 pos.push_back(j - SonStr.size());
76             j = j - i;
77             ComStr = SonStr.substr(0, i - 1);
78             for (int q = 1; q < ComStr.size(); q++)
79             {
80                 tmp1=ComStr.substr(q, ComStr.size() - 1);
81                 tmp2=ComStr.substr(0, ComStr.size() - 1 - q);
82                 if (tmp1 == tmp2)
83                     len++;
84             }
85             j = j + i-len;
86             i = 0;
87             len = 0;
88         }
89     }
90     return pos;
91 }

总之,KMP的核心思想在于:通过部分匹配字符串的长度来决定待匹配字符串的移动长度,而不是每次只是移动一位。

 

posted @ 2019-08-26 16:58  少年π  阅读(236)  评论(0编辑  收藏  举报