【字符串】Hash表

一.定义

哈希表是一种数据结构,它使用散列函数将数据存储在数组中,并使用哈希值快速查找数据。哈希表可以帮助我们快速插入、查找和删除数据,时间复杂度为O(1),因此它是一种非常高效的数据结构。哈希表通常用于实现数据缓存、字典和其他数据存储方案。(来源于ChitGPT)

二.制表

(1)十进制辅助理解

当我们拿到十进制数时,可以表达为这样

198=1*100+9*10+8;他的位权值分别为:100,10,1;

11451=1*10^{4}+1*10^{3}+4*10^{2}+5*10^{1}+1*10^{0}

那为什么我们要乘以位权值呢?

因为十进制数不乘以位权值的话就是这样了:

678=6+7+8=21;

579=5+7+9=21;

那么21是表达678?还是579?

如果我们乘以位权值就可以巧妙的化解这个矛盾了。

(2)字符串

让我们回忆一下ASCII:

当我们看到97是就可以想到‘a’;

当我们看到100时就可以想到‘d’;

那么‘ad’怎么表示呢?

难道是97+100=197?但'bc'怎么表示呢?还是98+99=197。

那么197表示'bc'?还是'ad'?

这时我们就要想到上面的位权值思想了;

若有26个字母,我们把位权值定义为int B=26;

当拿到'ad'时就可以表达为97*26^{1}+100*26^{0}=2622;

'bc'=98*26^{1}+99*26^{0}=2647;

这样我们就能保证没有重复了,2622也只能表示为'ad'。

(3)用函数表达

定义s='abcd';和h[]数组。

可以定义成这样:

const int B=26;
char a[4]={0,'a','b','c'};
int h[4];
for(int i=1;i<=strlen(a);i++){
	h[i]=h[i-1]*B+a[i];
}

三.查找

(1)十进制辅助理解

我们知道当有一个数:114时,如果我们想拿到14就可以114-1*10^{2}=14;

123456,我们想拿到456时就可以123456-123*10^{3}=456;

这样我们可以总结出结论:

定义十进制数(非字符串,只是用abc表示)abcde,要求cd,因为len(cd)=2;

则cd=abcd-ab*10^{len}

即abcd-ab*10^{2}

ps:如果不理解可以自己画一画看看。

(2)字符串

先定义进制 int B=26;

当拿到‘abcde’,让我们求'de'的话:'abcde'-'abc'*26^{2}

其他和十进制数一样,只是进制的区别

我们可以总结出规律:

定义字符串'abcde'当要求'cd'时就:

strlen(cd)=2;

'cd'='abcd'-'ab'*B^{len}

即:'cd'='abcd'-'ab'*26^{2}

(3)用函数表达

当总字符串是string s=0"abcd"; //0要把下标0的位置占了

求子字符串"cd"时:

len=cd.length()=2

"cd"=h[5]-h[5-len]*B^{len}

即"cd"=h[5]-h[3]*B^{2}

四.哈希冲突

(1)定义

指的是当两个或多个不同的数据具有相同的哈希值时发生的现象

(2)举个栗子

int(max)=2147483647;

int(min)=-2147483628;

所以2174783648超界会自动转换为-2147483648;

那么-2147483648不超界时也是-2147483648;

那么-2147483648是表达哪一个呢?

所以这就是hash冲突。

(3)解决方案

当我们把2个大数分别取模两个互质的数AB,这样得到的数ansa1,ansa2和ansb1,ansb2一定ansa1!=ansb1&&ansa2==ansb2,这样就巧妙的解决了hash冲突。(至于为什么要这样取模是数学领域研究的问题,可以记住结论就行)

一般我们分别取模1e9+7和1e9+9

具体应用见下一期:hash表的应用

五.总结

hash是处理字符串问题中不可缺少的元素,具体应用见下一期:hash表的应用

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值