POJ 1200 Crazy Search

  我的第一题字符串哈希。

  ac代码

#include<stdio.h>

#include<iostream>
#include<string.h>
using namespace std;
#define ll long long
#define maxn 16000005

int n,base;
int ss[maxn];
int vis[500];
char s[maxn];
int main()
{
    scanf("%d %d %s",&n,&base,s+1);
    memset(vis,-1,sizeof(vis));
    int len=strlen(s+1);
    int cnt=0;
    ll ans=0;
    for(int i=1;i<=len;i++)
    {
        if(vis[s[i]]==-1)
        {

            vis[s[i]]=cnt++;

        }
        ss[i]= vis[s[i]];

    }
    //cout<<cnt<<endl;
    long long hsh=0;
    if(len<n)
        printf("%lld\n",ans);
    else
        {
            ll qz=1;
            for(int i=1;i<=n;i++)
            {
                hsh=(ll)(hsh*base+ss[i]);
                if(i<=n-1)
                    qz*=base;


            }
            s[hsh]='*';//把字符串s转化为整数序列后,s就没有用了,我索性拿来做标记,标记哪些子串统计过了
            ans++;
            for(int i=n+1;i<=len;i++)
            {
                hsh-=ss[i-n]*qz;
                hsh*=base;
                hsh+=ss[i];
                if(s[hsh]!='*')
                {
                    s[hsh]='*';
                    ans++;
                }

            }
             printf("%lld\n",ans);

        }
    return 0;
}

贴一个我的另外一个代码,用的另一种方法但是一直wa,至今没找到bug

#include<stdio.h>
#include<iostream>
#include<map>
#include<string.h>
using namespace std;
#define ll long long
const int maxn=16000005;
map<ll,ll>mp;
ll ihash[maxn]={0};
char s[maxn];
const ll mod1=1e9+7;
const ll base=79;
long long k=1;
int n,nc;
int main()
{
    mp.clear();
    scanf("%d %d %s",&n,&nc,s+1);
    int len=strlen(s+1);
    ll ans=0;
    for(int i=1;i<=len;i++)
    {
        ihash[i]=(ihash[i-1]*base+(ll)s[i])%mod1;
        if(i<=n)
            k=k*base;

    }
   // cout<<endl;
   // for(int i=1;i<=len;i++)
     //   cout<<ihash[i]<<" ";
   // cout<<endl;
    for(int low=1;low<=len+1-n;low++)
    {
        int up=low+n-1;
        ll tmp=ihash[up]-ihash[low-1]*k;
        if(tmp<0)
            tmp+=mod1;
        //cout<<"tmp:"<<tmp<<endl;
        if(mp[tmp]==0)
        {
            mp[tmp]=1;
            ans++;
        }


    }
    printf("%lld\n",ans);
    return 0;

 

posted @ 2018-08-09 15:11  eason99  阅读(59)  评论(0编辑  收藏  举报