/*
kmp算法的主要作用在于对next数组的运用,所以这里只给出next数组的模板
性质1:对于每一个长度len的子串,该子串的最小循环节为len-next[len]
性质2:kmp的next不断向前递归的过程可以保证对于每一个当前前缀,都有一段后缀与之对应
*/ #include <iostream>
#include <cstring>
#include <algorithm>
using namespace std; const int maxn = 1e6+5;
int Next[maxn];
char mo[maxn];
int n2; void GetNext() {
int i = 0, j = -1; while (i < n2) {
if(j == -1 || mo[i] == mo[j]) {
i++;
j++;
Next[i] = j;
} else j = Next[j];
}
return;
} int main() {
cin >> mo; n2 = strlen(mo);
Next[0] = -1;
GetNext(); return 0;
}
/*
kmp模板
题意就是求B串在A串中的第一次匹配的下标,(从1开始)
str就是A,mo就是B
*/ #include<bits/stdc++.h>
using namespace std ; const int maxn = 1e6+5;
int Next[maxn], n1, n2;
char str[maxn], mo[maxn]; void GetNext() {
int i = 0, j = -1; while(i < n2) {
if(j == -1 || mo[i] == mo[j]) {
i++;
j++;
Next[i] = j;
} else j = Next[j];
}
return;
} int kmp() {
int cnt = 0;
int i = 0, j = 0; while(i < n1) {
if(j == -1 || str[i] == mo[j]) {
i++;
j++;
} else j = Next[j]; //next数组寻找与当前后缀匹配最长的前缀,省略不必要的查找
if(j == n2) return i - n2 + 1; //首地址
}
return -1;
} int main() {
cin >> str >> mo; n1 = strlen(str);
n2 = strlen(mo);
Next[0] = -1;
GetNext();
cout << kmp() << endl; return 0;
}
/*
kmp模板
题意就是求B串在A串中的出现次数(可重叠
str就是S,mo就是B
*/ #include<bits/stdc++.h>
using namespace std; const int maxn = 1e6+5;
int Next[maxn], n1, n2;
char str[maxn], mo[maxn]; void GetNext() {
int i = 0, j = -1; while(i < n2) {
if(j == -1 || mo[i] == mo[j]) {
i++;
j++;
Next[i] = j;
} else j = Next[j];
}
return;
} int kmp() {
int cnt = 0;
int i = 0, j = 0; while(i < n1) {
if (j == -1 || str[i] == mo[j]) {
i++;
j++;
} else j = Next[j];
if(j == n2) {
cnt++;
j=Next[j]; //完成一次匹配,将j移动到最长的前缀处,省略不必要的查找
}
}
return cnt;
} int main() {
cin >> str >> mo; n1 = strlen(str);
n2 = strlen(mo);
Next[0] = -1;
GetNext();
cout << kmp() << endl; return 0;
}
/*
kmp模板
题意就是求B串在A串中的出现次数(不可重叠
str就是A,mo就是B
*/ #include<bits/stdc++.h>
using namespace std; const int maxn = 1e6+5;
int Next[maxn], n1, n2;
char str[maxn], mo[maxn]; void GetNext() {
int i = 0, j = -1; while (i < n2) {
if (j == -1 || mo[i] == mo[j]) {
i++;
j++;
Next[i] = j;
} else j = Next[j];
}
return;
} int kmp() {
int cnt = 0;
int i = 0, j = 0; while (i < n1) {
if (j == -1 || str[i] == mo[j]) {
i++;
j++;
} else j = Next[j];
if (j == n2) {
cnt++;
j = 0;
}
}
return cnt;
} int main() {
cin >> str >> mo; n1 = strlen(str);
n2 = strlen(mo);
Next[0] = -1;
GetNext();
cout << kmp() << endl; return 0;
}
/*
最小循环节 POJ 2406 Power Strings
结论:如果len%(len-nxt[len])=0,那么循环次数为len/(len-nxt[len]),否则为1
*/ #include <cstdio>
#include <cstring>
using namespace std; char s[1000100];
int nxt[1000100]; void get_nxt(){
int len = strlen(s);
nxt[0] = -1;
int i = 0, j = -1; while (i < len){
if (j == -1 || s[i] == s[j]){
i++, j++;
nxt[i] = j;
}
else j = nxt[j];
}
} int main(){
//freopen("in.txt", "r", stdin);
while (scanf("%s", s)){
int len = strlen(s);
if (len == 1 && s[0] == '.')break; get_nxt(); int ans = len % (len - nxt[len]) == 0 ? len / (len - nxt[len]) : 1;
printf("%d\n", ans); }
return 0;
}

最新文章

  1. The Myths about Transactions (ACID) and NoSQL
  2. 2015暑假多校联合---Mahjong tree(树上DP 、深搜)
  3. Java_Servlet 中文乱码问题及解决方案剖析
  4. 深入理解ServletRequest与ServletResponse
  5. 多校5 1004 HDU5784 统计锐角三角形数目
  6. Linux 解压/压缩操作命令
  7. IOS后台执行机制 与 动作
  8. 用C++类模板实现栈结构出现的问题以及思考
  9. 啊我V办我偶看篇未改片考i
  10. select查询原理
  11. oracle恢复一个数据表的方法
  12. 希尔排序(shell‘ sort)
  13. Django:(博客系统)添加文章(中文)出现UnicodeEncodeError乱码
  14. SharePoint2013 功能区的配置
  15. 在webpack里使用jquery.mCustomScrollbar插件
  16. vue中使用swiper-slide时,循环轮播失效?
  17. PHPsql
  18. Map的嵌套
  19. 迅为IMX6开发板支持全网通4G模块丨GPS模块丨WIFI蓝牙丨千兆以太网
  20. Centos7.5.1804永久生效修改主机名

热门文章

  1. Explain的详细使用
  2. mysql 禁止自动提交设置
  3. 分布式NoSQL数据库MongoDB初体验-v5.0.5
  4. iframe父子页面js之间的调用
  5. centos7使用Dockerfile(docker-compose)运行jar包
  6. c(++)变长参数之整形(非字符串类型类似)
  7. 【LeetCode】457. Circular Array Loop 环形数组是否存在循环 解题报告(Python)
  8. 【LeetCode】437. Path Sum III 解题报告(Python)
  9. 1105 第K大的数
  10. 1281 - New Traffic System