poj_2752 kmp
题目大意
给定字符串S,求出S的所有可能相同前后缀的长度。比如:
"alala"的前缀分别为{"a", "al", "ala", "alal", "alala"}, 后缀分别为{"a", "la", "ala", "lala", "alala"}. 其中有{"a", "ala", "alala"}是相同的,即输入1,3,5.
题目分析
首先,根据题目的意思,一个串本身就是它的相同前后缀。然后,考虑长度稍小一点的前后缀:
有了kmp算法的next数组(保存某段子串的相同前后缀的最大长度,不包括自身),可以从最长的相同前后缀开始考虑,对于串S,根据next[strlen(S)-1]得到的最长相同前后缀为S1,则再根据next[strlen(S1)-1]得到的S1的最长相同前后缀S2肯定也为S的相同前后缀。(通过画图可以很容易的证明)。
这样,通过不断的向前查找next数组,得到一系列的相同前后缀。下面证明这些前后缀包含了所有的相同前后缀:
由于我们得到的是一系列最长相同前后缀,假设有一个相同的前后缀Sk不属于这些通过next递推得到的前后缀集合,那么len(Sk)必定小于len(S1),且Sk必定为S1的子串(通过画图很容易看出来);此时若Sk是S1的最长前后缀,则与前提Sk不为某一子串的最长前后缀矛盾,那么Sk不是S1的最长前后缀,则可以退出len(Sk)必定小于S2,且Sk必定为S2的相同前后缀..... 数学归纳递推下去,可以知道Sk要么为某个Si的最长前后缀,要么len(Sk) = 0. 这样可以证明这些通过next数组递推得到的前后缀包含了所有的相同前后缀
实现(c++)
#define _CRT_SECURE_NO_WARNINGS
#define MAX_WORD_LEN 400005
#include<stdio.h>
#include<string.h>
int gNext[MAX_WORD_LEN];
char gWord[MAX_WORD_LEN];
int gLength[MAX_WORD_LEN];
void GenerateNext(const char* sub_str, int* next, int len){
next[0] = 0; //next[i]表示sub_str[0, i]中最长相同前后缀的长度
for (int i = 1; i < len; i++){
int j = next[i - 1];
while (sub_str[j] != sub_str[i]){ //不断回溯,每次利用next数组来确定下一个需要判断的位置
if (j == 0){
j = -1;
break;
}
j = next[j - 1];
}
if (j < 0)
next[i] = 0;
else
next[i] = j + 1;
}
}
int GetPreSuffix(int* next, int len){
int i = len;
int count = 0;
while (next[i-1]){
gLength[count++] = i;
i = next[i-1];
}
gLength[count++] = i;
return count;
}
int main(){
while(scanf("%s", gWord)!= EOF){
int len = strlen(gWord);
GenerateNext(gWord, gNext, len);
int count = GetPreSuffix(gNext, len);
for (int i = count - 1; i >= 0; i --)
printf("%d ", gLength[i]);
printf("\n");
}
return 0;
}
poj_2752 kmp的更多相关文章
- POJ_2752 Seek the Name, Seek the Fame 【KMP】
一.题目 POJ2752 二.分析 比较明显的KMP运用. 但是这题不是只找一个,仔细看题后可以发现相当于是在找到最大的满足条件的后缀后,再在这个后缀里面找满足条件的后缀. 可以不断的运用KMP得出答 ...
- KMP POJ 2752 Seek the Name, Seek the Fame
题目传送门 /* 题意:求出一个串的前缀与后缀相同的字串的长度 KMP:nex[]就有这样的性质,倒过来输出就行了 */ /************************************** ...
- KMP算法求解
// KMP.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include<iostream> using namespac ...
- 简单有效的kmp算法
以前看过kmp算法,当时接触后总感觉好深奥啊,抱着数据结构的数啃了一中午,最终才大致看懂,后来提起kmp也只剩下“奥,它是做模式匹配的”这点干货.最近有空,翻出来算法导论看看,原来就是这么简单(先不说 ...
- KMP算法
KMP算法是字符串模式匹配当中最经典的算法,原来大二学数据结构的有讲,但是当时只是记住了原理,但不知道代码实现,今天终于是完成了KMP的代码实现.原理KMP的原理其实很简单,给定一个字符串和一个模式串 ...
- 萌新笔记——用KMP算法与Trie字典树实现屏蔽敏感词(UTF-8编码)
前几天写好了字典,又刚好重温了KMP算法,恰逢遇到朋友吐槽最近被和谐的词越来越多了,于是突发奇想,想要自己实现一下敏感词屏蔽. 基本敏感词的屏蔽说起来很简单,只要把字符串中的敏感词替换成"* ...
- [KMP]【学习笔记】
Oulipo Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 36916 Accepted: 14904 Descript ...
- KMP算法实现
链接:http://blog.csdn.net/joylnwang/article/details/6778316 KMP算法是一种很经典的字符串匹配算法,链接中的讲解已经是很明确得了,自己按照其讲解 ...
- KMP专题
1.[HDU 3336]Count the string(KMP+dp) 题意:求给定字符串含前缀的数量,如输入字符串abab,前缀是a.ab.aba.abab,在原字符串中出现的次数分别是2.2.1 ...
随机推荐
- 【Unity】用代码给按钮动态添加点击事件
问题:多数情况下用UGUI的Button控件身上的OnClick()列表可以指明该按钮点击后触发的回调.现在想要调用自定义脚本里的方法,当这个脚本挂在Button所属的Canvas身上时,传入Canv ...
- gsm at 指令
一.一般命令 AT+CGMI 给出模块厂商的标识. SONY ERICSSON AT+CGMM 获得模块标识.这个命令用来得到支持的频带(GSM900,DCS1800或PCS1900).当模块有多频带 ...
- java clone对象
本文转载至 http://blog.csdn.net/shootyou/article/details/3945221 现在Clone已经不是一个新鲜词语了,伴随着“多莉”的产生这个词语确实很“火”过 ...
- Spark读取文件
spark默认读取的是hdfs上的文件. 如果读取本地文件,则需要加file:///usr/local/spark/README.md. (测试时候发现,本地文件必须在spark的安装路径内部或者平行 ...
- [转]Handler学习笔记(二)
一.一个问题 有这样一个问题值得我们思考,若把一些类似于下载的功能(既耗时且不一定有结果)写在Activity(主线程)里,会导致Activity阻塞,长时间无响应,直至页面假死(如果5秒钟还没有完成 ...
- rails rake 版本问题
rails rake 版本问题 通常情况下,如果我们电脑上同时装了不同版本的rake时,运行rake命令时会出错,如: rake db:migrate rake aborted! You have a ...
- tab标签
<ul class="nav nav-tabs" role="tablist" role="tablist" id="myT ...
- Python 字符串切片
#-*- coding:utf-8 -*- #字符串切片 names = "abcdefgh" ''' 切片语法 names[起始位置:终止位置:步长] 起始位置:即字符串的下标, ...
- Spring 4 官方文档学习(十)数据访问之JDBC
说明:未修订版,阅读起来极度困难 1.Spring框架JDBC的介绍 Spring JDBC - who does what? 动作 Spring 你 定义连接参数 是 打开连接 是 指定SQ ...
- dm8127-内存分配
在前天一直完车辆捕获算法和车牌识别算法之后,算法移植告一段落,五月份以来,总算有点欣慰了,可是cmos采集视频有点问题,主要是前端采集不是我接手,嵌入式部门的小宋和小李负责,据说是20多万没了图纸,防 ...