您的位置:首页 > 其它

字符串hash问题

2015-10-11 15:33 316 查看
一些介绍字符串hash的文章:

字符串哈希函数

String

题目传送:HDU - 4821 - String

13年长春现场赛的字符串水题。。

不过没有接触过这类题,所以不会做。。

所谓字符串hash,通常是把一个字符串映射为一个整数。

我这里采用的是BKDRHash函数。稳定性最好的一个字符串hash函数。

AC代码:

#include <map>
#include <set>
#include <list>
#include <cmath>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <complex>
#include <cstdlib>
#include <cstring>
#include <fstream>
#include <sstream>
#include <utility>
#include <iostream>
#include <algorithm>
#include <functional>
#define LL long long
#define INF 0x7fffffff
using namespace std;

#define ULL unsigned long long

const int maxn = 100005;

int m, l;

char s[maxn];

ULL base[maxn];//base[i]存i个seed相乘的值
ULL Hash[maxn];//Hash[i]存后缀i的Hash值
ULL seed = 31;//用于映射出去,为了减少冲突,通常取31,131等等这样的质数

map<ULL, int> mp;//用于判重

int main() {
base[0] = 1;
for(int i = 1; i <= maxn; i ++) base[i] = base[i - 1] * seed;
while(scanf("%d %d", &m, &l) != EOF) {
scanf("%s", s);
int len = strlen(s);
Hash[len] = 0;
for(int i = len - 1; i >= 0; i --) {//字符串hash
Hash[i] = Hash[i + 1] * seed + s[i] - 'a' + 1;
}
int ans = 0;
for(int i = 0; i < l && i + m * l <= len; i ++) {
mp.clear();
for(int j = i; j < i + m * l; j += l) {
mp[Hash[j] - Hash[j + l] * base[l]] ++;
}
if(mp.size() == m) ans ++;
for(int j = i + m * l; j + l <= len; j += l) {
ULL tmp = Hash[j - m * l] - Hash[j - (m - 1) * l] * base[l];
mp[tmp] --;
if(mp[tmp] == 0) mp.erase(tmp);
tmp = Hash[j] - Hash[j + l] * base[l];
mp[tmp] ++;
if(mp.size() == m) ans ++;
}
}
printf("%d\n", ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  string hash 函数