HihoCoder第三周与POJ2406:KMP算法总结
HihoCoder第三周:
输入
第一行一个整数N,表示测试数据组数。
接下来的N*2行,每两行表示一个测试数据。在每一个测试数据中,第一行为模式串,由不超过10^4个大写字母组成,第二行为原串,由不超过10^6个大写字母组成。
其中N<=20
输出
对于每一个测试数据,按照它们在输入中出现的顺序输出一行Ans,表示模式串在原串中出现的次数。
样例输入
5
HA
HAHAHA
WQN
WQN
ADA
ADADADA
BABABB
BABABABABABABABABB
DAD
ADDAADAADDAAADAAD
样例输出
3
1
3
1
0
KMP于我的理解就是通过记录已经匹配的字符的情况,防止不必要的匹配。记录已经匹配字符的单元实际就是next数组,我其实觉得想法非常巧妙的一点在于,模式串与原串匹配,正常来讲总是会想跟原串或许会有什么关系,因为要记录已经匹配的字符嘛。但是相反,next只是跟模式串有关,原理就在于
如果一个字符串满足这个条件:有一个整数k,使得
p0 p1 ...pk-1 pk = pj-k pj-k+1...pj-1 pj
这样我下一次匹配不成功的时候,原串中的j就不用回溯,模式串中的i=next[i],因为你本身是满足这个条件的,所以当moshi[i]不相等的时候,我就不用从第0个字符从头开始试是否相等,而只需从moshi[next[i]]开始匹配即可。
next数组就是记录这个字符之前有多少字符和整个字符串最开始的相应的字符相等的。
之后就是如何求next数组。
求的时候本身就可以用递归来求:
如果moshi[i]==moshi[j]
那么i++;
j++;
moshi[j]= i;这里i代表从头开始的前缀,j代表后缀
如果不相等
那么i=next[i];
代码:
#include <iostream>
#include <cstring>
using namespace std; char moshi[10004],yuanchuan[1000004];
int calnext[1000004]; void Calnext(int len1)
{
memset(calnext,0,1000004*sizeof(int)); calnext[0]=-1; int i,j=-1; for(i=0;i<len1+1;)
{
if(moshi[i]==moshi[j]||j==-1)
{
i++;
j++;
if(moshi[i]==moshi[j])//calnext[i]==calnext[j]
{
calnext[i]=calnext[j];
}
else
{
calnext[i]=j;
}
}
else
{
j=calnext[j];
}
}
} int Cal(int len1,int len2)
{
int result=0;
int i=0,j=0;
//仔细想一下,j其实是一直往前走的!!!!!它没有回去的时候!!!!
while(i<len1&&j<len2)
{
if(moshi[i]==yuanchuan[j])
{
i++;
j++;
}
else
{
if(calnext[i]==-1)
{
i=0;
j++;
}
else
{
i=calnext[i];
}
}
if(i>=len1)
{
result++;
i=calnext[len1];
}
}
return result;
} int main()
{
int count;
cin>>count; while(count--)
{
cin>>moshi;
cin>>yuanchuan; int len1 = strlen(moshi);
int len2 = strlen(yuanchuan); Calnext(len1); cout<<Cal(len1,len2)<<endl; } return 0;
}
之前遇到的两个问题都在注释中了,一个是改进求解next数组时,应该是判断moshi是否相等,而跟next没什么关系。
比方说在匹配abc,c处错误,可能就跳到之前abd处,你只需判断c和d是否相等,如果相等了,说明这里不用再记录d的位置了,记录d如果不相等时会跳到哪里吧,可能是再之前的abf处。如果按照我之前的想法简直就解释不了了,abc,匹配c时出问题,跳转到abd处,你判断d可能会跳到f处,这里,然后你把c也弄到f哪里根本解释不同。(这里仅仅为我错误又很缥缈的思路。。。。)
第二个就是我受了暴力搜索的影响,其实看别人写的暴力,也是就一个循环,原串中的j也是不用回溯的,用一个k表示就好,不相等的话k置成0即可。我还弄了两层循环,好不麻烦。结果就是写了next数组之后还是两层循环,还是timelimited。真是。。。。在kmp算法中,j只是会一味的往前走,不能回头。所以一层循环,所以时间复杂度就是O(m+n)。
POJ2406:
Description
Given two strings a and b we define a*b to be theirconcatenation. For example, if a = "abc" and b = "def" thena*b = "abcdef". If we think of concatenation as multiplication,exponentiation by a non-negative integer is defined in
 the normal way: a^0 ="" (the empty string) and a^(n+1) = a*(a^n).
Input
Each test case is a line of input representing s, a string ofprintable characters. The length of s will be at least 1 and will not exceed 1million characters. A line containing a period follows the last test case.
Output
For each s you should print the largest n such that s = a^n forsome string a.
Sample Input
abcd
aaaa
ababab
.
Sample Output
1
4
3
代码:
#include <iostream>
#include <cstring>
using namespace std; char moshi[1000004];
int calnext[1000004]; void Calnext(int len1)
{
memset(calnext,0,1000004*sizeof(int)); calnext[0]=-1; int i,j=-1; for(i=0;i<len1;)
{
if(moshi[i]==moshi[j]||j==-1)
{
i++;
j++;
calnext[i]=j;
}
else
{
j=calnext[j];
}
}
} int main()
{
while(true)
{
scanf("%s",moshi); if(strcmp(moshi, "."))
{
int len1 = strlen(moshi); Calnext(len1); if(len1%(len1-calnext[len1])==0)
{
cout<<len1/(len1-calnext[len1])<<endl;
}
else
{
cout<<'1'<<endl;
} }
else
break; } system("pause");
return 0;
}
POJ2406这道题有意思的地方在于求next[len1],想一想就是abcabc#,如果#这里不匹配的话会跳转到a那里,即是位置3。如果是abdab#,会跳转到d那里,即是位置2。
所以我的理解就是当next[len1]这个值如果大于等于一半的len1的话,那么这个字符串就是powerstring。而如何把单元重复的长度求出来,就是len1-next[len1](试想一下abcabcabcabc#这样的字符串,它会记录的是最大的k是9,即前缀和后缀重叠了的是9,所以未重叠部分其实就是单位的abc,所以有多少个abc呢,结果就是 除以就好了。)
小弟弱傻痴菜,还望路人多多指正,互相交流。
版权声明:本文为博主原创文章,未经博主允许不得转载。
HihoCoder第三周与POJ2406:KMP算法总结的更多相关文章
- POJ2406 KMP算法
		
POJ2406 问题重述:给定字符串s0,记连续的k个s前后相连组成的s0s0...s0为s0^k.输入字符串S,求最大的k,使得S = s0^k. 问题分析: 1.采用kmp算法求出前缀函数 pre ...
 - poj2406(kmp算法)
		
Given two strings a and b we define a*b to be their concatenation. For example, if a = "abc&quo ...
 - 【算法•日更•第三十一期】KMP算法
		
▎前言 这次要讲的HMP算法KMP算法很简单,是用于处理字符串的,之前一直以为很难,其实也不过如此(说白了就是优化一下暴力). ▎处理的问题 通常处理的问题是这样的:给定两个字符串s1和s2,其中s1 ...
 - POJ2406 kmp算法next数组-串的最小循环节/循环周期
		
题目链接:http://poj.org/problem?id=2406 题目大意:问给出的字符串最多由多少个子串相乘得来的. 思路:利用next数组的含义来解. 1.一个串的最小循环节长度:len - ...
 - kmp算法详解
		
转自:http://blog.csdn.net/ddupd/article/details/19899263 KMP算法详解 KMP算法简介: KMP算法是一种高效的字符串匹配算法,关于字符串匹配最简 ...
 - 算法起步之kmp算法
		
[作者Idlear 博客:http://blog.csdn.net/idlear/article/details/19555905] 这估计是算法连载文章的最后几篇了,马上就要 ...
 - KMP算法的时间复杂度与next数组分析
		
一.什么是 KMP 算法 KMP 算法是一种改进的字符串匹配算法,用于判断一个字符串是否是另一个字符串的子串 二.KMP 算法的时间复杂度 O(m+n) 三.Next 数组 - KMP 算法的核心 K ...
 - hihoCoder #1015 : KMP算法【KMP裸题,板子】
		
#1015 : KMP算法 时间限制:1000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi和小Ho是一对好朋友,出生在信息化社会的他们对编程产生了莫大的兴趣,他们约定好互相帮助,在 ...
 - hihoCoder 1015 KMP算法(kmp)
		
#1015 : KMP算法 时间限制:1000ms 单点时限:1000ms 内存限制:256MB 描写叙述 小Hi和小Ho是一对好朋友,出生在信息化社会的他们对编程产生了莫大的兴趣.他们约定好互相帮助 ...
 
随机推荐
- sql语句插入时提示:“Duplicate entry 'XXX' for key 1 ” 是什么原因?
			
你用的是MYSQL 数据库吧? 1:提示信息翻译:插入 xxx 使索引1重复分析:索引如果是primary unique这两两种,那么数据表的数据对应的这个字段就必须保证其每条记录的唯一性.否则就会产 ...
 - Hive的学习之路(理论篇)
			
一.Hive介绍 Apache官网给出的logo,一半是Hadoop大象的头,一半是蜜蜂的身体,也是寓意着它是基于Hadoop,哈哈,纯属个人理解,进入正题. Hive是基于Hadoop的一个数据仓库 ...
 - pandas help
			
1. read_csv read_csv方法定义: pandas.read_csv(filepath_or_buffer, sep=', ', delimiter=None, header='infe ...
 - MySQL 远程连接问题 (Linux Server)
			
Mysql Workbench 连接Ubuntu上的Mysql时报如下错误: 原因:查看 /etc/mysql/mysql.conf.d/mysqld.cnf # # Instead of skip ...
 - 在visual studio中快速添加代码段
			
昨天我在网课上,看到老师输入#2之后,立马就出现了一堆代码. 我于是赶紧打开自己的visual studio尝试一下,并没有任何反应. 上网查找,发现visual studio有自定义代码段的功能. ...
 - centos7 ip配置及ssh服务连接
			
一.配置ip /etc/sysconfig/network-scripts/ifcfg-ens33 ifcfg-ens33 这个是配置网卡的配置文件,名字可能不一样,大概为:ifcfg-网卡名 TYP ...
 - lower_bound() 函数使用详解
			
简介 lower_bound()函数是用来求一个容器中,第一个大于等于所要查找的元素的地址,具体的原理是二分查找,因此它只能用于非降序序列. 他有三个参数,第一个参数是容器的初始地址,第二个参数是容器 ...
 - PAT A1114 Family Property
			
用并查集处理每个家庭的信息,注意标记~ #include<bits/stdc++.h> using namespace std; ; bool visit[maxn]={false}; i ...
 - 吴裕雄 Bootstrap 前端框架开发——Bootstrap 显示代码:按键提示
			
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...
 - B: 最小代价
			
B: 最小代价 题解:先用最小生成树求联通所有点的最小代价ans 在求度为1的时候权值最大的点mx ans-mx就是答案 #include<iostream> #include<al ...