目录
前言
哈希算法是必须掌握的一种基础算法,在一些比较出名的竞赛acm、蓝桥杯,并且在一些公司面试题中都可能会出现,而且作为简单题我们必须要拿下,所以我们要引起重视,下面让我们来深入了解哈希算法。
一、什么是哈希算法
哈希算法,也称为散列算法,是一种数学函数或算法,它能够将任意长度的数据(称为“消息”)转换为固定长度的字符串(称为“哈希值”或简称“哈希”)。
二、哈希算法的原理
哈希算法的原理是将输入的数据按照一定的规则进行运算,从而得到一个固定长度的输出。具体来说,算法会将输入的数据分割成若干个等长或不等长的块,每个块称为一个消息块。然后,对每个消息块进行一系列的位运算、移位运算、模运算、异或运算等,从而得到一个中间结果,称为一个消息摘要。最后,将所有消息摘要进行组合或再次运算,从而得到最终的输出,即哈希值。
三、哈希算法的特点
1.高效性:计算速度快,能够快速生成哈希值。
2.唯一性:不同的输入数据生成的哈希值几乎不可能相同(尽管存在极小的碰撞概率)。
3.不可逆性:根据哈希值无法推导出原始输入数据,这是哈希算法的重要安全特性。
四、哈希算法的应用场景
1.数据安全:哈希算法可以用来验证数据的完整性和来源,例如数字签名、校验和、指纹等。通过比较数据经过哈希算法得到的哈希值是否相同,可以判断数据是否被篡改或伪造。
2.数据检索:哈希算法可以用来构建高效的数据结构,例如哈希表、布隆过滤器、默克尔树等。通过使用哈希值作为键或节点,可以实现快速的数据插入、删除和查找。
3.数据分片:在分布式系统中,哈希算法可以用于数据分片,以便将海量数据分布到多台机器上进行并行处理。
4.负载均衡:通过哈希算法,可以对客户端IP地址或会话ID计算哈希值,然后将取得的哈希值与服务器列表的大小进行取模运算,最终得到的值就是应该被路由到的服务器编号。这样可以实现会话粘滞的负载均衡策略。
5.分布式存储:在分布式存储系统中,哈希算法可以用于确定数据的存储位置。例如,通过哈希算法对数据取哈希值,然后对机器个数取模,得到的最终值就是应该存储的缓存机器编号。此外,一致性哈希算法还可以解决机器扩展时的数据迁移问题。
五、经典例题
1.字符统计
(帅哥这个蓝色字体可以点进去看原题)
代码题解
#include <iostream>
#include<string>
#include<unordered_map>
using namespace std;
int main()
{
string s;
cin >> s;
int hash[256] = {0};//用于记录每个字母出现次数
for(int i = 0; i < s.size(); i++){
hash[s[i]]++;
}
int maxc = 0;
char ret[256];//结果数组用于存储出现次数最多的字母
int retSize = 0;//最长字母个数
for(char c = 'A'; c <= 'Z'; c++){
if(hash[c] > maxc){
maxc = hash[c];
retSize = 0;//如果发现更长的字母就把结果数组长度变为0,0下标的值变成新的最多字母
ret[retSize++] = c;
}
else if(hash[c] == maxc){//如果发现最长字母的个数一样多就把这个字母插入结果数组
ret[retSize++] = c;
}
}
ret[retSize] = '\0'; //把这个结果数组变成字符串
cout << ret << endl;
return 0;
}
2.字符串统计
(帅哥这个蓝色字体可以点进去看原题)
代码题解
#include <iostream>
#include<string>
#include<unordered_map>
using namespace std;
int main()
{
// 请在此输入您的代码
unordered_map<string,int> m;
int n;
cin>>n;
string s;
for(int i=0;i<n;i++){
cin>>s;
m[s]=1;//给该键标记存在了
}
cout<<m.size()<<endl;
return 0;
}
3.优质数对
(帅哥这个蓝色字体可以点进去看原题)
代码题解
#include <iostream>
#include<unordered_map>
using namespace std;
#define ll long long
#define sb 1000000001
int a[100001],b[100001];
int main()
{
// 请在此输入您的代码
int n;
cin>>n;
for(int i=0;i<n;i++)cin>>a[i];
for(int i=0;i<n;i++)cin>>b[i];
unordered_map<ll,int>h;
ll ret=0;
for(int j=0;j<n;j++){//a[i]=b[j] b[i]=a[j],优质数对的条件
ll x=(ll)a[j]*sb+b[j];//哈希表的查找过程
ret+=h[x];
ll y=(ll)b[j]*sb+a[j];//哈希表的插入过程
h[y]++;
}
cout<<ret<<endl;
return 0;
}
六、结语
学习算法是一个很艰难,漫长的过程,我们要克服一切困难,学习算法本就是由易到难,我相信通过我们坚持不懈的努力一定能理解并熟练掌握其中细节,加油,我相信你一定能行。
关注我让我们一起学习编程,希望大家能点赞关注支持一下,让我有持续更新的动力,谢谢大家。