第五章 ALDS1_4_C:Dictionary 散列表
来源:互联网 发布:tp框架隐藏index.php 编辑:程序博客网 时间:2024/06/06 00:29
知识点
链表
- 概念
- 根据元素的值通过某种运算(通过函数计算出相应的值)确定元素的存储位置,然后将元素保存到相应的位置。
- 插入、搜索、删除都是通过函数计算出相应的值,再根据值去到存储位置进行操作,这些过程基本是
O(1) 的操作。 - 计算函数尽量能将各种值存储在不同的位置,但是也有总有“冲突”(不同的值计算出来的结果一样的情况),这时候需要解决冲突的方法:开放地址法(数组)、拉链法(链表)
- 实现方法
- 数组
- 链表
问题链接
ALDS1_4_C:Dictionary
问题内容
题目有两个操作,分别是插入insert和查找find。添加字符串和查找字符串,其中字符串只包含A、C、G、T四种字母。对于find操作返回是否能找到相应的key。
思路
代码中解决冲突的是双散列结构的开放地址法。若出现冲突,调用第二个散列函数来求散列值。
代码
#include<iostream>#include<cstdio>#include<cstring>using namespace std;typedef long long LL;const LL maxx = 1000000 + 10;char H[maxx][15];// 将字符转换为数值LL CharToInt(char ch) { if (ch == 'A') return 1; if (ch == 'C') return 2; if (ch == 'G') return 3; if (ch == 'T') return 4; return 0;}// 将字符串转成数值并生成keylong long getKey(char str[]) { LL sum = 0, p = 1; LL len = strlen(str); for (long long int i = 0; i < len; i++) { sum += p * CharToInt(str[i]); p *= 5; } return sum;}LL h1(LL key) { return key % maxx;}LL h2(LL key) { return 1 + (key % (maxx - 1));}// find 操作bool find(char str[]) { LL key, h; key = getKey(str); for (LL i = 0;; i++) { h = (h1(key) + i * h2(key)) % maxx; //找到key if (strcmp(H[h], str) == 0) return true; // key不存在 else if (strlen(H[h]) == 0) return false; } return false;}// insert操作void insert(char str[]) { LL key, h; key = getKey(str); for (LL i = 0;; i++) { h = (h1(key) + i * h2(key)) % maxx; //找到key if (strcmp(H[h], str) == 0) return ; // key不存在 else if (strlen(H[h]) == 0) { // 插入 strcpy(H[h], str); return ; } }}int main() { int n, q, key; char str[20], op[20]; for (int i = 0; i < maxx; i++) H[i][0] = '\0'; scanf("%d", &n); for (int i = 0; i < n; i++) { scanf("%s %s", op, str); if (op[0] == 'i') insert(str); else { if (find(str)) printf("yes\n"); else printf("no\n"); } } return 0;}
阅读全文