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;
}

  

posted @   Painting、时光  阅读(477)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示