【哈希&KMP模板题】-POJ-3461-Oulipo

题目链接:http://poj.org/problem?id=3461

题目描述:给一个子串再给一个主串,问子串在主串中出现了多少次。裸题一道,用来试验哈希和kmp模板

解题思路&AC代码:

(哎呀我去。。这题都要背下来了  = =

①--HASH
首先,我觉得哈希好写还好理解,先写了一个哈希的代码,所谓哈希就是给字符串生成一个哈希值,也就是算出一个数来,用这个数来代表这个字符串,显然对数的操作都是o(1)的,所以就达到了减小时间复杂度的作用。

有几个问题应该说明一下,因为一共就26个字母,所以取31进制比较好,然后这要是错了的话就改成1e6+7啥的试试,一般错不了,算哈希值的时候通常为了方便比较还会搞出一个hash数组来,计算这个数组的时候从后面往前算能使计算方便一点。需要再次强调的是哈希值只能“存储”这个字符串的信息,因为通常没几下就爆了ll,取模后的值就没什么数学意义了,千万不要拿哈希值去做“数学计算”!

不多说了。。贴代码

#include 
#include 
#include 

using namespace std;
typedef unsigned long long ll;
const int base = 31;
const int maxn = 1000050;

char sub[maxn],str[maxn];
ll xp[maxn];
ll hash[maxn];

int main()
{
    int T,i;
    scanf("%d",&T);

    xp[0]=1;
    for(i=1;i=0;i--)
        {
            sub_num=sub_num*base+sub[i];
        }

        hash[n]=0;
        for(i=n-1;i>=0;i--)
        {
            hash[i]=hash[i+1]*base+str[i];
        }

        int ans=0;
        for(i=0;i<=n-L;i++)     ///Caution!!! it is (i<=n-L) or (i




②--KMP

接下来是用KMP方法解决匹配问题,这个算法有点难以理解,我到现在也没完全搞明白,先拿模板这么用吧,且敲且理解。。。

子串与主串匹配的时候,一旦失配,朴素的算法上子串回溯到头,主串往后走一位,这是有浪费的

比如:

P: a b c a b e

S: a b c a b k a b c

e和k比失配了,我们没必要朴素算法那样回溯,而是把S串中c那个位置对准到k那个位置继续比较,这样做是因为ab先匹配上后面才有戏,所以KMP算法就搞出了一个next数组,next【i】存放的是一旦到 i 失配,我们该回溯到子串的什么位置。

如何计算出next数组是KMP算法的难点,事实上我们可以理解为next【i】代表了 i 以前的字符串的“自我重合度”。求next【i】的过程就是找 i 前面字符串的“前缀、后缀最长重合长度”。我们设 i , j 变量分别表示前后缀的最后字符位置,相等,那么欢天喜地都加一,失配,那么 i 回溯到next【i】,用这样一种递推似的思想来求出整个next数组。

以上理解说实话我心里也没底。。要多敲题再体会体会。。唉。。讲得太快了,每节例会的内容我觉得都够搞一个星期的。。。明天比赛了,不知道能不能进省赛,,加油吧~

#include 
#include 
#include 

using namespace std;
const int maxn = 1000100;

char p[maxn],s[maxn];
int next[maxn];
int lenp,lens;

int KMP()
{
    int i=0,j=0,ans=0;
    while(i



你可能感兴趣的:(基础算法题例,字符串)