上一章,我们讲了hash表的数据结构,并简单实现了hash表的初始化与删除操作,这一章我们会讲解Hash函数和实现算法,并手动实现一个Hash函数。

Hash函数

本教程中我们实现的Hash函数将会实现如下操作:

  • 输入一个字符串,然后返回一个0m(Hash表的大小)的数字
  • 为一组平常的输入返回均匀的bucket索引。如果Hash函数不是均匀分布的,就会将多个记录插入到相同的bucket中,这就回提高冲突的几率,而这个冲突就会影响到我们的Hash表的效率。

Hash算法

我们将会设计一个普通的字符串Hash函数,在伪代码中表示如下:

function hash(string, a, num_buckets):hash = 0string_len = length(string)for i = 0, 1, ..., string_len:hash += (a ** (string_len - (i+1))) * char_code(string[I])hash = hash % num_bucketsreturn hash

这个Hash函数主要分为两步:

  1. 将字符串转为大整型
  2. 通过取余数mod m将整数的大小减小到固定范围

变量a是一个素数,并且要大于英文字母,我们正在散列ASCII字符串,其字母大小为128,因此我们应该选择大于此的素数。

char_code这个函数会返回字母对应的整数,使用的是ASCII中的字母。

如下使用这个Hash函数

hash("cat", 151, 53)// 函数拆解
hash = (151**2 * 99 + 151**1 * 97 + 151**0 * 116) % 53
hash = (2257299 + 14647 + 116) % 53
hash = (2272062) % 53
hash = 5

如果改变a我们会得到不同的结果:

hash("cat", 163, 53) = 3

代码实现

// hash_table.c
static int ht_hash(const char* s, const int a, const int m) {long hash = 0;const int len_s = strlen(s);for (int i = 0; i < len_s; i++) {hash += (long)pow(a, len_s - (i+1)) * s[i];hash = hash % m;}return (int)hash;
}

什么是冲突?

理想中的散列函数返回的结果都是均匀分布的,但是,对于任意一个散列函数,总会有一些输入经过散列后,得到相同的值。如果要找到这组输入,我们就需要测试大量的输入数据。

因为上面提到的有不好的输入存在,意味着所有输入都没有完美的散列函数。所以在设计散列函数时,针对预期输入,我们的散列函数需要表现最好。

不好的输入也存在安全问题,如果某个恶意用户向哈希表提供了一组冲突密钥,那么搜索这些密钥将比正常情况(O(1))花费更长时间(O(n))。这可以用作针对以哈希表为基础的系统(例如DNS和某些Web服务)的拒绝服务攻击。

上一章:Hash table数据结构
下一章:冲突处理


原文地址:https://github.com/jamesroutley/write-a-hash-table/tree/master/03-hashing

转载于:https://www.cnblogs.com/bilberry/p/10264535.html

[译]C语言实现一个简易的Hash table(3)相关推荐

  1. 十位数连加 c语言,用C语言编写一个简易计算器可实现加减乘除,连加连减,连乖连除....

    用C语言编写一个简易计算器可实现加减乘除,连加连减,连乖连除. 用C语言编写一个简易计算器可实现加减乘除,连加连减,连乖连除. 人气:435 ℃时间:2020-04-10 06:55:13 优质解答 ...

  2. 用go语言撸一个简易版的区块链

    用go撸一个简易版的区块链 引言 这个最初的版本时多年以前学习go的时候,自己撸的一个简易版本的区块链.不过麻雀虽小,五脏俱全.通过这个代码你了解区块链内部的大概运行机制时没有问题的. 比特币底层区块 ...

  3. C语言-实现一个简易的银行排号叫号系统

    这两天在网上看到这个题目,感觉挺有意思,就做了一下.我在网上看到其他人都是用C++做的,因为不懂C++语言,没看懂,尝试着用C语言做了该题.希望能来看该题的大神指点指点,估计还有些bug没找出来. 本 ...

  4. 使用java语言编写一个简易的计算器(完整代码与详细步骤都有哦!)

    [案例介绍] 1.案例描述 本案例要求利用Java Swing 图形组件开发一个可以进行简单的算术运算的图形化计算器. 2.运行结果 运行结果 [案例目标] 学会分析"简易计算器" ...

  5. 用C语言设计一个简易的选择题答题系统

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言 一.设计简易的答题系统 二.使用步骤 1.引入库 2.读入数据 总结:应用随机数,getchar以及if else 前 ...

  6. 用java编写一个简易功能画板_用Java语言编写一个简易画板

    讲了三篇概博客的概念,今天,我们来一点实际的东西.我们来探讨一下如何用Java语言,编写一块简易的画图板. 一.需求分析 无论我们使用什么语言,去编写一个什么样的项目,我们的第一步,总是去分析这个项目 ...

  7. 使用Java语言搭建一个简易的局域网直播(live)系统

    演示一下 局域网直播系统,顾名思义是运行在局域网中的系统,整个直播系统由两部分构成:录制和播放,核心思路是推拉流和流转码. 录制直播 录制直播使用的是自己电脑的摄像头和麦克风,使用Java自带的JFr ...

  8. 用c语言编写一个简易的编译器,面向教学的简易c语言编译器的设计与实现(54页)-原创力文档...

    目录 TOC \o "1-5" \h \z \o "Current Document" 摘要I ABSTRACTII \o "Current Docu ...

  9. C语言编写一个简易的网络词典

    摘要:电子辞典是指将传统的辞典中的内容转换为数字格式存储的文件,并且将它们保存在存储器中.用户使用时只需要通过键盘输入需要查询的条目,电子辞典通过自身携带的处理器,按照一定的编码查询方式便可以找到相关 ...

最新文章

  1. Velocity文档(3)
  2. 计算机工程实践,【计算机工程论文】计算机工程实践能力培养(共3056字)
  3. 树莓派 系统的 启动与安装
  4. VTK:Filtering之TriangulateTerrainMap
  5. 【速看,双100%】剑指 Offer 14- I. 剪绳子 I
  6. 从前序与中序遍历序列构造二叉树
  7. build 之前执行task_浅谈VS编译自定义编译任务—MSBuild Task(csproject)-阿里云开发者社区...
  8. spring boot中的注解
  9. LNMP一键安装包+Thinkphp搭建基于pathinfo模式的路由(可以去除url中的.php)
  10. FMS直播和点播测试
  11. 立春好消息:华章图书持续霸榜京东、当当计算机畅销新书榜!
  12. 栅格数据灰度化并前端转换展示
  13. 国内哪家虚拟主机比较好
  14. Shiro session过期跳转到登录页面问题
  15. 腾讯技术分享:微信小程序音视频与WebRTC互通的技术思路和实践
  16. 这10种神级性能优化手段,你用过几个?
  17. html emmet输入法_Emmet HTML参考
  18. PowerShell 7.1 中的新增功能
  19. 10 个 MySQL 经典错误【转】
  20. Chrome内置的断网Javascript 小游戏脚本示范

热门文章

  1. 如何使用SAP Cloud for Customer里的ABSL代码调用Web service
  2. ANSYS-CFX,计算时报错,内存参数报错,return code 1【终极解决方案】
  3. java中multiply用法_java中BigDecimal加减乘除基本用法
  4. tensorflow生成图片标签_Tensorboard高维向量可视化 + 解决标签和图片不显示BUG
  5. 动态规划|最大k乘积问题(C语言)
  6. 用ANSYS画矩形_钢轨打磨用复合砂轮磨削温度场的研究
  7. python os.system关闭log_又到牛市!带你学习一个python强大证券数据分析工具
  8. 电脑卡顿不流畅是什么原因_为什么安卓系统用久了会卡,苹果系统却依然流畅?原因找到了!...
  9. android 权限管理框架,Android 运行时权限管理最佳实践
  10. 孩子数学成绩不好怎么办_孩子数学成绩不好怎么办