字符串与hash(一)

之前有一种普遍使用的字符串hash:
hash[i+1]=(hash[i]\cdot base+s[i])MOD(mod)

可以有效地处理字符串的子串:

再者:还有可以代替KMP的hash:

hash=(hash\cdot base+s[i])MOD(mod)

+

hasht=(hasht\cdot base-s[i]\cdot tmp+s[i+strlen(s)])MOD(mod)

//tmp=\prod _{i=1}^{strlen(s)-1}base

现在我们从一道题目入手(SPOJ-EPALIN):

题意:

对给定字符串S,求以S为前缀的、长度最小的回文串并输出它

网上由两种解法:

一、KMP+逆字符串

二、hash+回文

我还有一种解法:马拉车+标记以S[LEN-1]为结尾的最长回文串长度的左端点

HASH回文:

1.回文的特点:

假设我们有一个回文串:

S_i,S_{i+1}.....S_{n-2},S_{n-1}

根据回文串特点:

我们有:(条件一)

S_i=S_{n-1}

S_{i+1}=S_{n-2}

..

..

首先,从一般的hash式子,我们有:(式子一)

hash1=(hash1*base+s[i])MOD(mod)//i: len-1 \Rightarrow 0

之后,简化式子,我们有:(式子二)

hash1=S_i+S_{i+1}\cdot base+...+S_{n-2}\cdot base^{n-2}+S_{n-1}\cdot base^{n-1}

又因为:有条件一:
所以:hash1=S_{n-1}+S_{n-2}*base+...+S_{i+1}\cdot *base^{n-2}+S_i\cdot base^{n-1}式子二)

我们令式子二的值为hash2

所以有了等价关系:

 hash1=hash2

ORZ.....

CODE:

#include <cstdio>
#include <cstring>
#include <algorithm>
typedef unsigned long long ull;
const int MAXN = 100000+100;
const int prime = 107;
const int mod = 1e9+7;
int n;
char s[MAXN];
int main()
{
    while(~scanf("%s",s))
    {
        n=strlen(s);
        ull pow=1;
        ull start=0;
        ull a1=0,a2=0;
        for(int i=n-1;i>=0;--i)
        {
            a1=(a1*prime+s[i])%mod;
            a2=(a2+pow*s[i])%mod;
            //printf("%d %d\n",a1,a2);
            if(a1==a2)
                start=i;
            pow=(pow*prime)%mod;
        }
        for(int i=0;i<n;++i)
            putchar(s[i]);
        for(int i=start-1;i>=0;--i)
            putchar(s[i]);
        printf("\n");
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值