Hash函数经典用法

撰写这篇文章之前,先谈下个人对程序员编程素养的理解:

        程序员除了数据结构与算法,什么也不属于自己---记得哪个NB人物曾经说过这样的话。的确,程序员水平高低如何,很大程度上取决于基本功是否扎实。高级程序员与普通码农的区别在我看来就是对这些基础知识是否做到了运用自如。许多程序员开发程序也是简单地调用已有系统库,或者第三方组件,写写简单的hello world或者if...else之类的程序,这样下去其个人竞争优势逐渐散失,很容易被新手赶超,究其原因在于平时没有对常见的基础知识打牢固,也没有对常见的技巧做总结,当然这里说的基础只是面向编程(可能还涉及到系统相关知识,暂且不论)所需的基础,包括语言语法知识,常见的数据结构算法技能等。也有不少程序员也仅仅停留在语言使用上面,至于为什么这么用不考究,语言贵在熟练而不在多,在我看来程序员掌握一种编译型语言(C/C++)与一种脚本语言(比如Shell或者Perl/Python/Php)就够了,在熟练掌握熟悉语言情况之下其他语言学起来成本也很低。就拿我们Linux C/C++编程来说,首先得熟练掌握C/C++编程语言语法知识,包括常见的语法及雷区,然后进一步则需要搞懂其内部实现原因,比如C++内存对象模型,虚函数实现原理。STL各类容器底层实现机制等,这样用起来也会因为其了解其原理而做到游刃有余。现实中,我们往往忽视这一点,常常因为一个小细节问题搞得焦头烂额,追根溯源就是因为平时对理论基础不牢固导致。我们学习数据结构也是一样,知道常见的数据结构及其应用场景,才能在多变的问题中设计出合适的程序算法来。这就要我们平时训练过程中,不断提升个人的问题抽象能力,同时加深对操作系统,设计模式,网络编程等知识的理解,通过项目中遇到的问题难点来巩固基础。 既然说程序的灵魂就是数据结构加对应的算法,语言本身只是一门工具而已,那么就大可不必为了花大量时间在语言学习上了。我个人不是特别喜欢学习C++大量的语法特性,学习时间长,成本高,效率较低(不做嵌入式或者某些对性能要求较高的项目一般不用考虑用它了),当然毕竟与C语言语法相似,在平时也需要用C++来完成一些工具开发,掌握其基本语法还是有必要的。如今有不少好用的第三方库,比如boost、QT、ACE等,可以帮助我们高效开发,而不用自己造轮子了。不过,虽然个人工作大多数时候只用C语言这一门简洁的语言,但是语言并不是孤立的,需要结合操作系统,数据结构与算法等一起来综合考虑。平时自己用各类语言编程时,考虑到了每一行代码底层是如何运转的,语言帮我们实现了什么,需要我们做什么。实际上编程修炼的也就是自己对现实问题的抽象能力,通过对实际问题的剖析,抽象出好的数据结构,用合理高效地算法去解决该问题。就拿个人来说,自己在这几年时间内也读过了不少计算机经典书籍,同时结合对项目的理解,也算是对基础的一个弥补吧。当然很高级的数据结构和算法现在没有涉及,比如什么B,B+树,红黑树,图论相关的,动态规划或其他领域内的算法(KNN分类算法,谱聚类算法,朴素贝叶斯算法等)。毕竟我也只是一个应用程序开发者,不是搞基础算法研究的学者,比如大多数人只需了解C++ STL中某些容器的底层实现及它们的应用场景就够了,比如vector实际上就是一个动态数组; list,deque实现了其双向链表;map, multimap, set,multiset其底层实现利用了红黑树,该数据结构默认就是已经排序的等等。

        下面具体回到hash链表的运用及实现上吧。为什么会出现hash这种数据结构呢,其实还是为了时间效率上的考虑,hash算法是一种典型的利用空间换取时间的算法,如果选取hash函数比较好,其hash值分布比较均匀,可以在O(1)时间内查找到所需的值。我们知道,数组具有随机存取功能,由于其空间在内存中连续分布,所以数组读取数值是相当快的;而链表这种数据结构,对于数据的增删有优势,但是对于访问某值的话,则需要从头结点找起,效率则有些低。而hash则是结合了这两者的优点。说的直观点就是将一大类数据用已知的hash函数进行分类,映射到固定大小的数组中,如果某一些数据不相同,但是通过映射之后,分到了同一类中(value值相同),则用链表来维护一组冲突域值。如果hash函数选取的好,则m个元素映射到n个slot(我们这里将数组index称之为槽)的平均查找时间为O(m/n)。可以这样说,hash算是分类的链表数组。hash具有查找效率高与去重功能,如果有此应用场景,考虑此数据结构

先看一个简单的hash应用吧,统计单词词频:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define HASHLEN 2807303
typedef struct node
{
    char *word; //单词
    int count; //单词统计词频
    struct n
  • 9
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值