在做POJ1200 遇到最大的问题是,不知道怎么把不定的字符转换成对应的进制数,用于计算哈希值,
以及误以为会有需要处理哈希冲突,使用了链表处理,结果超时。。
简单暴力使用一个哈希数组就可以了,题目已经说明不同的字符串不会超过16000000,而char[16000000] 也就15M左右,、
不会超内存。
自己总结三点:
1) 256个字符映射成对应的无符号整数 (也可以看成是哈希。。)
2)有M个不同字符的字符串,可以看做M进制数
3) 字符串映射成一个整数值,M即为累乘因子(哈希函数)
#include<stdio.h>
#include<malloc.h>
#define MAX_H 16000000
#define MAX_LEN 16000000
#define MAX_CHAR_SIZE 256
struct Node {
long long hashKey;
struct Node *next;
};
typedef Node CNode;
char text[MAX_LEN+1];
int charNum[MAX_CHAR_SIZE + 1] = { 0 };
int N, NC;
bool isExist[MAX_H + 2] = { 0 };
//CNode *hashmap[MAX_H + 1] = { 0 };
//CNode *creatCNode() {
// CNode *cNode = (CNode *)malloc(sizeof(CNode));
// cNode->hashKey = 0;
// cNode->next = NULL;
// return cNode;
//}
//
//void putInHashMap(long long hsKey) {
// long long hsIndex;
// hsIndex = hsKey% MAX_H;
// CNode *cNode = (CNode *)malloc(sizeof(CNode));
// cNode->hashKey = hsKey;
// if (hashmap[hsIndex] == NULL) {
// hashmap[hsIndex] = cNode;
// }
// else {
// cNode->next = hashmap[hsIndex];
// hashmap[hsIndex] = cNode;
// }
//}
//
//CNode *getCNode(long long hsKey) {
// long long hsIndex;
// hsIndex = hsKey% MAX_H;
// CNode* cNode = hashmap[hsIndex];
// while (cNode != NULL) {
// if (cNode->hashKey == hsKey) {
// return cNode;
// }
// cNode = cNode->next;
// }
// return NULL;
//}
long long bkrdHash(int from) {
long long hs = 0;
int i;
for (i = 0; i < N; i++) {
hs = hs * NC + charNum[text[from + i]];
}
return hs;
}
int main() {
int i = 0;
long long hsKey;
int count = 0;
int charCnt = 1;
freopen("input.txt", "r", stdin);
scanf("%d %d", &N, &NC);
scanf("%s", &text);
i = 0;
while (text[i] != '\0') {
if (charNum[text[i]] == 0) {
charNum[text[i]] = charCnt++;
}
i++;
}
i = 0;
while (text[i + N-1] != '\0') {
hsKey = bkrdHash(i);
//if (getCNode(hsKey) == NULL) {
// putInHashMap(hsKey);
// count++;
//}
if (isExist[hsKey] == 0) {
//putInHashMap(hsKey); // 加多即超时 !!!!! 1S 内!!!
isExist[hsKey] = true;
count++;
}
i++;
}
printf("%d\n", count);
return 0;
}