poj 2406 求最短重复字串

题解:

KMP中next数组的巧妙运用。在这里我们假设这个字符串的长度是len,那么如果len可以被len-next[len]整除的话,我们就可以说len-next[len]就是那个最短子串的长度为什么呢? 假设我们有一个字符串ababab,那么next[6]=4对吧,由于next的性质是,匹配失败后,下一个能继续进行匹配的位置,也就是说,把字符串的前四个字母,abab,平移2个单位,这个abab一定与原串的abab重合(否则就不满足失败函数的性质),这说明了什么呢,由于字符串进行了整体平移,而平移后又要重叠,那么必有s[1]=s[3],s[2]=s[4],s[3]=s[5],s[4]=s[6].说明长度为2的字符串在原串中一定重复出现,这就是len-next[len]的含义!(啰嗦的很,对于一个字符串,它的最短重复子串长度为len-knext[len])

ac代码:

#include <cstdio>
#include <cstring>
#include <iostream>
#define mt(a) memset(a,0,sizeof(a))
using namespace std;
int knext[1000005];
void getknext(char s[],int len)
{
    mt(knext);
    int i=0;
    int j=-1;
    knext[i]=j;
    while(i<len)
    {
        if(j==-1 || s[i]==s[j])
        {
            i++;
            j++;
            knext[i]=j;
        }
        else j=knext[j];
    }
}
char s[1000006];
int main()
{
    while(~scanf("%s",s))
    {
        if(s[0]==‘.‘) break;
        int len=strlen(s);
        getknext(s,len);
        int temp=len-knext[len];
        if(len%temp==0) cout<<len/temp<<endl;
        else cout<<1<<endl;
    }
    return 0;
}
时间: 2024-12-27 21:54:33

poj 2406 求最短重复字串的相关文章

hdu 4333 扩展kmp+kmp重复字串去重

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4333 关于kmp next数组求最短重复字串问题请看:http://www.cnblogs.com/z1141000271/p/7406198.html 扩展kmp请看:http://www.cnblogs.com/z1141000271/p/7404717.html 题目大意:一个数字,依次将第一位放到最后一位,问小于本身的数的个数及等于本身的个数和大于本身的个数,但是要注意重复的不再计算 题解:

网上有些例子有问题,所以重新写了下 求字符串的最长不重复字串

假设有一个字符串"abcdebfgh" 那么最长不重复字串是"cdebfgh",长度是7 若是:abcdbefbghijij 应输出:befbghij 以abcbef这个串为例 用一个数据结构pos记录每个元素曾出现的下标,初始为-1 从s[0]开始,pos['a'] == -1,说明a还未出现过,令pos['a'] = 0,视为将a"加入当前串",同时长度++ 同理令pos['b'] = 1,pos['c'] = 2 到s[3]时,pos['b

poj2406 kmp 求最小循环字串

Power Strings Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 47748   Accepted: 19902 Description Given two strings a and b we define a*b to be their concatenation. For example, if a = "abc" and b = "def" then a*b = "

POJ - 2406 ~SPOJ - REPEATS~POJ - 3693 后缀数组求解重复字串问题

POJ - 2406 题意: 给出一个字符串,要把它写成(x)n的形式,问n的最大值. 这题是求整个串的重复次数,不是重复最多次数的字串 这题很容易想到用KMP求最小循环节就没了,但是后缀数组也能写 后缀数组写法放在后面那一题,SPOJ - REPEATS是求子串类型,KMP就不好处理了 这里放下处理KMP的AC代码: 1 #include <cstdio> 2 #include <cstring> 3 #include <queue> 4 #include <c

POJ 3415 Common Substrings(后缀数组求重复字串)

题目大意:给你两个字符串,让你求出来两个字符串之间的重复子串长度大于k的有多少个. 解题思路: 先说论文上给的解释:基本思路是计算A的所有后缀和B的所有后缀之间的最长公共前缀的长度,把最长公共前缀长度不小于k的部分全部加起来.先将两个字符串连起来,中间用一个没有出现过的字符隔开.按height值分组后,接下来的工作便是快速的统计每组中后缀之间的最长公共前缀之和.扫描一遍,每遇到一个B的后缀就统计与前面的A的后缀能产生多少个长度不小于k的公共子串,这里A的后缀需要用一个单调的栈来高效的维护.然后对

找出字符串的最长不重复字串

这是我遇到的一道校招题目: 给定一字符串只包含数字,请写一个算法,找出该字符串中的最长不重复子串(不重复是指子串中每一元素不同于子串中其他元素) 如: "120135435"最长不重复子串为 "201354" 要求用java或者c来写,我用了java. /** * 思想: *      从头开始截取字符串,只要后一个元素不在截取的字符串里,就更新截取,多截取一个元素. *       如果发现后一个元素出现在字符串里, 将最后截取的字符串存为临时结果,开始位置后移一

最长无重复字串

给定一个字符串,找出不含有重复字符的最长子串的长度. 示例: 给定 "abcabcbb" ,没有重复字符的最长子串是 "abc" ,那么长度就是3. 给定 "bbbbb" ,最长的子串就是 "b" ,长度是1. 给定 "pwwkew" ,最长子串是 "wke" ,长度是3.请注意答案必须是一个子串,"pwke" 是 子序列  而不是子串. class Solution

poj1159(动态规划或者lcs求最长字串)

http://acm.hrbust.edu.cn/vj/index.php?c=problem-problem&id=20480 LCS求最长公共子串 #include<stdio.h> #include<iostream> #include<map> #include<string.h> #include<vector> using namespace std; short a[5005][5005]; char s1[5005]; c

LeetCode系列字符串操作(一)ZigZag输出,寻找最大不重复字串长度。

ZigZag Conversion The string "PAYPALISHIRING" is written in a zigzag pattern on a given number of rows like this: (you may want to display this pattern in a fixed font for better legibility) P A H N A P L S I I G Y I R And then read line by line