HDU1880——哈希表(BKDR算法)——魔咒词典
哈希表:
建表复杂度:O(n) k为字符串品均长度,n为字符串数目
查询 O(1) !!!
实现主要操作
1.把字符串进行实数化
2.把这个串存进去如果发现该位置为空,直接存,如果已经有了值,拉出一个链表
3.查询
该算法好像是不会产生冲突,因为一旦产生冲突,那么strcmp字符串函数就会对他们进行比较,虽然复杂度会高一些
转载出处——http://blog.csdn.net/hlyfalsy/article/details/9238537
蒟蒻只是做了一点解释
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 | /************************************************ * Author :Powatr * Created Time :2015-9-4 15:34:45 * File Name :Hash.cpp ************************************************/ #include <cstdio> #include <algorithm> #include <iostream> #include <sstream> #include <cstring> #include <cmath> #include <string> #include <vector> #include <queue> #include <deque> #include <stack> #include <list> #include <map> #include <set> #include <bitset> #include <cstdlib> #include <ctime> using namespace std; #define lson l, mid, rt << 1 #define rson mid + 1, r, rt << 1 | 1 typedef long long ll; const int MAXN = 3e6 + 10; const int INF = 0x3f3f3f3f; const int MOD = 1e6 + 7; const int BASE = 131; struct edge{ edge* next; char s[88]; }_hash[MAXN], *h[MOD], *cur; int Get_Id( char *s) { int Hash = 0; int len = strlen (s); for ( int i = 0 ; i < len ; i++) Hash = (Hash * BASE % MOD + s[i]) % MOD ; return Hash; //字符串转化 } void BKDR_HASH( char *s) { int code = Get_Id(s); //哈希表的头标志 edge* p = h[code]; //取的是地址(以该code为头标志的最后一个数的地址) while (p){ //如果没有到达头标志一直往上 if (! strcmp (p->s, s)) return ; else p = p->next; } strcpy (cur->s, s); cur->next = h[code]; //地址之间的赋值相当于数值之间的赋值,a = b,把b的地址改了不会影响a的 h[code] = cur++; } int find( char *s) { int code = Get_Id(s); edge* p = h[code]; while (p){ //全局变量初始的地址为0,局部变量有初始地址,不知道为什么如果这个地址不进行处理,默认为0 if (! strcmp (p->s, s)) return p - _hash; //p为当前串在哈希表上的地址,_hash是初始地址 else p = p->next; } return -1; } int main(){ cur = _hash; //注意如果printf("%d", cur);输出的是cur的地址,而不是值。。这个在异或上纠结了一会儿,其实每次读取cur只增加了2 char ss[100]; while (~ scanf ( "%s" , ss)){ if (ss[0] == '@' ) break ; getchar (); BKDR_HASH(ss); gets (ss); BKDR_HASH(ss); } int m; scanf ( "%d" , &m); getchar (); while (m--){ gets (ss); int id = find(ss); if (id == -1) printf ( "what?\n" ); else { char *node = _hash[id^1].s; if (node[0] == '[' ){ for ( int i = 1; node[i] != ']' ; i++) printf ( "%c" , node[i]); puts ( "" ); } else { puts (node); } } } return 0; } |
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步