字符串hash用法

3 篇文章 0 订阅
2 篇文章 0 订阅

什么是字符串哈希

其实字符串hash和我们平时在代码中使用的hash都是一样的,原理都是将字符串通过一系列算法,将他映射成一个N进制,并且我们要保证不同的字符串得到的N进制一定是不同的。

为什么要有字符串hash这个东西?试想一下,我们对大量的单词进行对比比较,看哪些单词是重复出现过的,我们首先要将单词转换成ascii码,然后再比较他们的ascii码是否相等,这样会不会太浪费空间和时间,我们不妨先计算出这个单词的hash,然后再保存在内存里,这样我们比较两个单词,直接比较他们的字符串hash即可。至于如何计算字符串hash,其实就跟我们计算二进制,八进制一样,只是有一点细节上的区别。

如何计算

假设我们有abcabb两个字符串,假设1=a,2=b,3=c…,英文字母有26个,我们其实可以设置26进制即可,但这样容易出现hash碰撞,所以我们设置大一点,随便一个数字就好,就36进制吧。

通过进制计算,我们得出:

hash(abc) = 1371

hash(abb) = 1370

由于在计算较长的字符串时,我们知道int最大可以保存2^31-1,如果字符串过长的话,肯定会出现溢出的情况,这个时候我们就要对结果取模,一般这儿设置一个较大的质数用来取模即可,我这里用的是1e+9 + 7这个数来进行取模,同时这个数刚好在int范围内。

所以我们可以得出一个计算字符串hash的公式。

其中 h 为返回值,初始为 0,p为所代表的进制,Si代表当前字符串第i个字符。

衡量hash的一个指标就是看hash碰撞率,如果某字符串越长越复杂,那计算出来的hash值进行取模后,可能会与其他字符串的hash值发生碰撞。

这个问题是不可避免的,你可以增大基数p或者增大模来降低hash碰撞,也可以采用其他的hash策略来计算hash。

总而言之,在平时刷题中,题目是不会出这种数据给你的,如果有,改变一下模的值就行了。

代码

我的cpp代码如下:

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

unsigned int MOD = 1e+9 + 7;

int getH(string s) {
    unsigned int h = 0;
    int n = s.size();
    int p = 36;         // 36进制
    for (int i = 0; i < n; ++i) {
        int c = s[i] - 'a' + 1;
        h = (h * p) % MOD + c;
    }
    return h;
}


int main() {
    cout << getH("abb") << endl;
    cout << getH("abc");
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值