ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

KMP算法模板

2021-01-20 18:03:57  阅读:185  来源: 互联网

标签:return int Next ++ 算法 tlen KMP else 模板


概述

模板出自kuangbin的博客

典型应用:

给你两个字符串,寻找其中一个字符串是否包含另一个字符串,如果包含,返回包含的起始位置。 

(1) 头文件

1 #include <bits/stdc++.h>
2 using namespace std;
3 const int N = 1e5+10;
4 int Next[N];
5 char S[N],T[N];   // S:主串  T:模式串
6 int slen,tlen;

(2) getNext()函数

 1 void getNext()
 2 {
 3     int j,k;
 4     j = 0;  k = -1; Next[0] = -1;
 5     while(j < tlen)
 6     {
 7         if(k == -1 || T[j] == T[k])
 8             Next[++j] = ++k;
 9         else 
10             k = Next[k];
11     }
12 }

(3) 返回模式串T在主串S中首次出现的位置

 1 // 返回模式串T在主串S中首次出现的位置
 2 // 返回的位置是从0开始的
 3 int KMP_Index()
 4 {
 5     int i = 0,j = 0;
 6     getNext();
 7 
 8     while(i < slen && j < tlen)
 9     {
10         if(j == -1 || S[i] == T[j])
11         {
12             i++;    j++;
13         }
14         else 
15             j = Next[j];
16     }
17     if(j == tlen)
18         return i-tlen;
19     else 
20         return -1;
21 }

(4) 返回模式串在主串S中出现的次数

 1 int KMP_Count()
 2 {
 3     int ans = 0;
 4     int i,j = 0;
 5 
 6     if(slen == 1 && tlen == 1)
 7     {
 8         if(S[0] == T[0])
 9             return 1;
10         else 
11             return 0;
12     }
13     getNext();
14     for(i = 0;i < slen;i++)
15     {
16         while(j > 0 && S[i] != T[j])
17             j = Next[j];
18         if(S[i] == T[j])
19             j++;
20         if(j == tlen)
21         {
22             ans++;
23             j = Next[j];
24         }
25     }
26     return ans;
27 }

(5) 全家福

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 /***************KMP***************/
 5 const int N = 1e5+10;
 6 int Next[N];
 7 char S[N],T[N];   // S:主串  T:模式串
 8 int slen,tlen;
 9 
10 void getNext()
11 {
12     int j,k;
13     j = 0;  k = -1; Next[0] = -1;
14     while(j < tlen)
15     {
16         if(k == -1 || T[j] == T[k])
17             Next[++j] = ++k;
18         else 
19             k = Next[k];
20     }
21 }
22 
23 // 返回模式串T在主串S中首次出现的位置
24 // 返回的位置是从0开始的
25 int KMP_Index()
26 {
27     int i = 0,j = 0;
28     getNext();
29 
30     while(i < slen && j < tlen)
31     {
32         if(j == -1 && S[i] == T[j])
33         {
34             i++;    j++;
35         }
36         else 
37             j = Next[j];
38     }
39     if(j == tlen)
40         return i-tlen;
41     else 
42         return -1;
43 }
44 
45 // 返回模式串在主串S中出现的次数
46 int KMP_Count()
47 {
48     int ans = 0;
49     int i,j = 0;
50 
51     if(slen == 1 && tlen == 1)
52     {
53         if(S[0] == T[0])
54             return 1;
55         else 
56             return 0;
57     }
58     getNext();
59     for(i = 0;i < slen;i++)
60     {
61         while(j > 0 && S[i] != T[j])
62             j = Next[j];
63         if(S[i] == T[j])
64             j++;
65         if(j == tlen)
66         {
67             ans++;
68             j = Next[j];
69         }
70     }
71     return ans;
72 }
73 /***************END***************/
74 
75 int main()
76 {
77     int TT;
78     cin >> TT;
79     while(TT--)
80     {
81         cin >> S >> T;
82         slen = strlen(S);
83         tlen = strlen(T);
84         cout << "模式串T在主串中首次出现的位置是: " << KMP_Index() << endl;
85         cout << "模式串T在主串S中出现的次数为: " << KMP_Count() << endl;
86     }
87     return 0;
88 }
View Code

(6) 补充

KMP的优化

 1 void getNext()
 2 {
 3     int j,k;
 4     j = 0,k = -1,Next[0] = -1;
 5     while(j < tlen)
 6     {
 7         if(k == -1 || T[j] == T[k])
 8         {
 9             j++,k++;
10             if(T[j] == T[k])
11                 Next[j] = Next[k];   // 直接走到下一个不相等的地方
12             else 
13                 Next[j] = k;
14         }
15         else 
16             k = Next[k];
17     }
18 }

Next[]数组求循环节
性质:

  • len-next[i]为此字符串的最小循环节(i为字符串的结尾) 
  • 另外如果len%(len-next[i])==0,此字符串的最小周期就为len/(len-next[i])
  • 如果len%(len-next[i]) != 0 则没有循环节???(小声逼逼)

标签:return,int,Next,++,算法,tlen,KMP,else,模板
来源: https://www.cnblogs.com/duny31030/p/14304217.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有