KMP的小小应用<一> hdu 3746

题目链接:      http://acm.hdu.edu.cn/showproblem.php?pid=3746

本来并不是看着一题的,搜代码时一不小心看到大牛说先看着题的找的规律,于是便拿来这题来看,于是惊叹发现曾经没思路的题,现在依然没思路,于是不理解的情况下,搜解释,终于搜到一句话:用KMP算法求最小循环节,这里有一个结论,最小循环节的大小为len-next[len]。于是便理解了好久,画了好几张纸,终于有所理解,于是自己按理解情况写了代码;还是有所反应的:

有个大牛代码,没看,但看了解释,对循环的解释,如果看怎么循环的,可以看一下,链接:http://www.cnblogs.com/Lyush/archive/2011/07/27/2118976.html

代码及注释如下:

View Code
#include<string.h>
#include<stdio.h>
int len;
char str[100001];
int next[100001];
void get_next()
{
int i,j;
j=-1;
next[0]=-1;
for(i=1;i<len;i++)
{
while(j>-1&&str[i]!=str[j+1])
j=next[j];
if(str[i]==str[j+1])
j++;
next[i]=j;
}
}
int main()
{
int t,n;
scanf("%d",&t);
getchar();
while(t--)
{
memset(next,0,sizeof(next));
gets(str);
len=strlen(str);
get_next();
n=len-(next[len-1]+1);////可以学着理解一下,其实最小循环节即为len-(next[len-1]+1);
if(len!=n&&len%n==0)///////////////len!=n就是字符长度不为1
printf("0\n");
else
printf("%d\n",n-len%n);////可以体会一下,应该是n-len%n;
}
return 0;
}
 
 

  

转载于:https://www.cnblogs.com/world-ding/articles/2144192.html

#include <iostream> #include <vector> using namespace std; // 构造单调性序列 vector<int> getPattern(const vector<int>& seq) { vector<int> pattern; for (int i = 1; i < seq.size(); ++i) { if (seq[i] > seq[i - 1]) pattern.push_back(1); else if (seq[i] < seq[i - 1]) pattern.push_back(-1); else pattern.push_back(0); } return pattern; } // 生成 KMP 的 failure 函数 vector<int> getFailure(const vector<int>& pattern) { int m = pattern.size(); vector<int> fail(m, 0); for (int i = 1, j = 0; i < m; ++i) { while (j > 0 && pattern[i] != pattern[j]) j = fail[j - 1]; if (pattern[i] == pattern[j]) j++; fail[i] = j; } return fail; } // KMP 算法主函数 vector<int> kmpSearch(const vector<int>& text, const vector<int>& pattern, const vector<int>& fail) { vector<int> positions; int n = text.size(), m = pattern.size(); for (int i = 0, j = 0; i < n; ++i) { while (j > 0 && text[i] != pattern[j]) j = fail[j - 1]; if (text[i] == pattern[j]) j++; if (j == m) { positions.push_back(i - m + 1); // 记录匹配位置 j = fail[j - 1]; // 继续匹配下个可能的位置 } } return positions; } int main() { int n, m, s; cin >> n >> m >> s; vector<int> A(n), B(m); for (int i = 0; i < n; ++i) cin >> A[i]; for (int i = 0; i < m; ++i) cin >> B[i]; // 获取单调性序列 vector<int> disA = getPattern(A); vector<int> disB = getPattern(B); // KMP 算法部分 vector<int> fail = getFailure(disB); vector<int> positions = kmpSearch(disA, disB, fail); // 输出结果 cout << positions.size() << endl; for (int pos : positions) cout << pos + 1 << endl; // 转换为题目要求的起始位置(从 1 开始) return 0; }
08-26
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值