您的位置:首页 > 其它

poj1200 hash

2015-03-08 19:18 190 查看
hash 其实一直想学的,但是一个是一直在刷 dp ,一个是各种要掌握的算法也很多,(别找理由了就是你懒……),总之在又一次 bc 出现hash但是我却茫然的时候,即使这道题不是简单 hash 就能做出来的,我也觉得真的一定要补一下这个算法了。

从鹏神的博客分类里面找了一道 hash 表的题目学习了一下然后做了一下

poj 1200:

题意:给定一个字符串,以及该字符串里字符的种类数 NC ,欲求规定长度为 N 的子串的种类数。

如果不知道 hash 这个算法,估计就是想个什么字符匹配的做法,可能也能做,但我估计超时的可能性也非常大,字典树貌似会但是我估计码起来应该也不简单,但既然这个是道 hash 做法,就往刚看的 hash 上靠,于是这个题目就出来了,其实 hash 表就是将一个串(或数组)的规定长度的子串(数组)看做一个 b 进制数(hash 值),不同子串的 hash 值相等的概率比较小,所以基本可以计算有多少个 hash 值就可以了。

而计算 hash 值的时候一般都是滚动优化,就是以上一个 hash 值减去少掉的一个元素再加上一个新的元素作为下一个 hash 值。本题中我取 b 为 NC,一般可以取

b 为 100000007,而本应计算完 hash 后 mod h,此时可以将 所有数定为 ull 型,则 hash 值自然溢出可以不 mod ,或 b 取题目中某个数,在 hash 值比较小的时候一般也可以不用 mod 。

我基本也是只粗略学习了一下 hash ,翔神告诉我 hash 一般用于字符串或者数组的判重。

顺便把这个被我DEBUG成狗屎一样的代码贴上来,WA了无数次的原因其实是```昂, c 数组初值为 0 ,而我给字母赋值时也用到了 0 ,于是``` NC 进制数就变成了 NC + 1 进制数Orz

#include<stdio.h>
#include<string.h>
/*
#define ll long long
#define ull unsigned long long
*/
bool hash[16000005];
int c[128];
char s[16000005];

int main(){
int N,nC;
while(scanf("%d%d",&N,&nC)!=EOF){
memset(c,-1,sizeof(c));
memset(hash,0,sizeof(hash));
scanf("%s",s);
unsigned long long t=0,tmp=1,NC = nC;
int ans=0;
int l=strlen(s),i,m=0,j;
//    printf("%c\n",s[0]);
for(i=0;i<l;i++){
//    printf("AAA\n");
if(c[s[i]]==-1){
c[s[i]]=m;
m++;
}
if(i==N-1){
for(j=0;j<=N-1;j++){
t+=c[s[j]]*tmp;
tmp*=NC;
}
hash[t]=1;
ans++;
tmp/=NC;
/*        int a;
a=t;
printf("%lld\n",t);
while(a){
printf("%lld",a%NC);
a/=NC;
}
printf("\n");*/
}

//    printf("\ntmp=%lld\n",tmp);
else if(i>N-1){
t/=NC;
/*    int a=t;
while(a){
printf("%lld",a%NC);
a/=NC;
}
printf("\n");*/
//    t-=c[s[i-N]]*tmp;
t+=c[s[i]]*tmp;
if(!hash[t]){
hash[t]=1;
ans++;
}
/*
a=t;
printf("\n");
printf("%lld\n",t);
while(a){
printf("%lld",a%NC);
a/=NC;
}
printf("\n");
*/
}
}//    printf("\ntmp=%lld\n",tmp);
//    printf("\n");
/*    for(i=0;i<=100000;i++){
if(hash[i]){
t=i;
while(t){
printf("%lld",t%NC);
t/=NC;
}
printf("\n");
}
}

printf("\n");

for(i=1;i<=127;i++){
if(c[i]>=0){

printf("%2c%2d",char(i),c[i]);
}
}

printf("\n");*/
printf("%d\n",ans);

}

return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: