字符串hash算法

本篇博客主要记录了 字符串hash 的相关算法,包括:
1. 字符串hash初步
2. 字符串hash进阶(还不一定什么时候写,初步的内容在大部分情况下是够用的)

概述

散列(hash)是一种常用的算法思想,是一种典型的以空间换时间的做法。
对于整数型的散列算法在一般的数据结构课程或书籍中都会教授,这两个名词不知道是否会激起您的一些记忆:散列函数冲突

这篇博客不讨论散列函数的构造和冲突的解决办法,主要记录的是字符串的散列算法。字符串hash是指将一个字符串S映射为一个整数,使得这个整数可以尽可能的唯一表示S。

字符串hash初步

字符串hash初步是讨论如何用一个整数唯一的表示一个字符串的问题。

首先来看这么一个问题:如何将一个二维整点坐标P(x,y)用一个整数唯一的表示?(其中0≤x,y≤range)

很容易想到的是 整数=x*range+y。

回到字符串hash初步讨论的问题上,想想它的解决方案

我们不妨设字符串S由A~Z这26个大写字母组成,再不妨把A~Z映射为0~25,这样就可以把26个字母对应到二十六进制中。
接着,按照二十六进制转换成十进制的方法,即可将这个S转换成一个十进制的数。由进制转换的结论可以知道,这个十进制的数是唯一的,于是上述问题得到解决,下面是实现:

int hashStr(char s[], int len){   //len:字符串的长度
    int id = 0;
    for(int i = 0; i < len; i++){
        id = id*26 + (s[i]-'A');
    }
    return id;
}

如果字符串中加入了小写字母(a~z)呢?
和上面一样,只需要将a~z映射成26~51即可,实现方法也是类似的。

对于字符串中还包含数字的情况,有两种处理办法:
1. 同小写字符的处理办法一样,将数字映射到52~61,即增加到了62进制
2. 如果确保末尾是确定个数的数字,直接将整数数位“接上”即可。比如“BCD4”:按照前面的方法,”BCD”转换成整数为731,那么“BCD4”表示为7314。即731*10+4。下面是这个例子的实现:

int hashStr(char s[], int len){
    int id = 0;
    for(int i = 0; i < len-1; i++){
        id = id*26 + (s[i]-'A');
    }
    id = id*10 + (s[len-1]-'0');
    return id;
}

参考资料
胡凡. 算法笔记[M]. 机械工业出版社, 2016. 106-111

你可能感兴趣的:(《算法笔记》学习笔记)