hash入门

来源:互联网 发布:农历日期 java代码 编辑:程序博客网 时间:2024/04/28 21:46

《挑战程序设计竞赛》P98

代码:

#include <bits/stdc++.h>using namespace std;const int M = 1046527;//必须是质数,这样可以比较好的避免hash冲突const int L = 14;//字符串的最大长度typedef long long LL;//样例输入://6 insrt AAA insert AAC find AAA find CCC insert CCC find CCCchar H[M][L];//保存字符串的数组//将一个字符串的每一个字符转成数字int char2num(char cha){    if (cha == 'A') return 0;    else if (cha == 'C') return 1;    else if (cha == 'G') return 2;    else if (cha == 'T') return 3;}//将字符串转换成数字,这里面的P相当于是P进制LL getkey(char str[]){    LL sum = 0, p = 1, i;    for (i=0;i<strlen(str); i++){        sum+=(p*char2num(str[i]));        p*=4;    }    return sum;}int h1(int key){    return key%M;}int h2(int key){    return 1+(key%(M-1));}//查找函数 bool find1(char str[]){    LL key, h;    key = getkey(str);    for (int i=0; ;i++){        h = (h1(key)+i*h2(key))%M;        if (strcmp(H[h], str) == 0) return true;        else return false;    }}//插入函数int insert1(char str[]){    LL key, h;    key = getkey(str);    for(int i=0; ;i++){        h = (h1(key)+i*h2(key))%M;        if (strcmp(H[h], str) == 0) return 1;        else if (strlen(H[h]) == 0){//一个括号的锅,我真是想操人,妈的为什么括号不匹配不报错啊!!!!!!!!!!!!!!            strcpy(H[h], str);            return 0;        }    }}int main(){    int i, n, h;    char str[L], comand[9];    for (int i=0; i<M; i++) H[i][0] = '\0';    scanf("%d", &n);    for (int i =0; i<n; i++){        scanf("%s %s",comand, str);        if (comand[0] == 'i'){            insert1(str);        }        else {            if (find1(str)){                cout<<"yes"<<endl;            }            else{                cout<<"no"<<endl;            }        }    }    return 0;}


核心的思想:将一个字符串转换成数字,通过数字来检索,效率是O(1)
难点:如何比较高效的得到一个数字(当输入的字符串数量较多时)(采取mod质数),以及h1()h2()函数的设计


原创粉丝点击