4.2.1 散列的定义与整数散列
1.散列的引入:
2.散列的概念:
1. 在N个数中,查询M个数是否存在
#include<iostream>
using namespace std;
const maxn=100010;
bool v[maxn]={false};
int main()
{
int n,m;
cin >> n >> m;
for(int i=0; i<n; i++)
{
int temp;
cin >> temp;
v[temp]=true;
}
for(int i=0; i<m; i++)
{
if(v[i]==true)
cout << "存在" << endl;
else
cout << "不存在" << endl;
}
return 0;
}
时间复杂度为:o(m+n)
2. 查询m个数中,在n中出现的次数:
#include<iostream>
using namespace std;
const maxn=100010;
int v[maxn]=0;
int main()
{
int n,m;
cin >> n >> m;
for(int i=0; i<n; i++)
{
int temp;
cin >> temp;
v[temp]++;
}
for(int i=0; i<m; i++)
{
int temp1;
cin >> temp1;
cout << temp1 << " " << v[temp1] << endl;
}
return 0;
}
时间复杂度为:o(m+n)
3. 散列的定义:
4. 常用的散列函数:
1. 直接定址法:
直接把key作为数组下标,是最常见最实用的散列应用或者是线性变换(H(key)=a*key+b)
2. 除留余数法
通过散列函数,可以把很大的数转化为不超过mod的整数,这样就可以将他作为可行的数组下标(注意,表长TSize必须不小于mod,不然会产生越界)
当mod是一个素数时,H(key)能尽可能覆盖[0,mod]范围内的每一个数。一般为了方便起见,取TSize是一个素数,而mod直接取成与TSize相等
5. 冲突:
1. 冲突原因:
2. 解决冲突的三种办法:
1.1 线性探查发(Linear Probing)
2. 平方探查法:(Quadratic probing)
3. 链地址法:(拉链法:)
4.2.2 字符串hash初步:
1.前言:
2.将大写字母A~Z转化为26进制:
int HashFunc(char S[], int len)
{
int id=0;
for(int i=0; i<len; i++)
id=26*i+S[i]-'A';
return id;
}
3.将大写字母A~Z和小写字母a ~z转化为52进制
int HashFunc(char S[],int len)
{
int id=0;
for(int i=0; i<len; i++)
{
if(s[i]>='A' && s[i]<='Z')
id=id*52+S[i]-'A';
else if(s[i]>='a' && s[i]<='z')
id=id*52+s[i]-'a'+26;
}
return id;
}
3.出现大写字母,小写字母,数字有两种方式处理方式:
3.1 按照小写字母的处理方法,增大进制数至62
int HashFunc(char S[],int len)
{
int id=0;
for(int id=0; id<len; id++)
{
if('A'<=s[i] && s[i]<='Z')
id=id*62+s[i]-'A';
else if('a'<=s[i] && s[i]<='z')
id=id*62+s[i]-'a'+26;
else if('0'<=s[i] && s[i]<='9')
id=id*62+s[i]-'0'+52;
}
}
3.2 如果保证在字符串的末尾是确定个数的数字,那么就可以把前面英文字母组成的字符串按照之前的思路转化为整数,再将末尾的数字直接拼上去
int HashFunc(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';
}
4.以一个问题结尾:
#include<iostream>
using namespace std;
const int maxn=100;
int HashTable[26*26*26+10]={0};
char S[maxn][5],temp[5]; //S[][]设置成2维数组,每一行表示1个字符串
int HashFunc(char S[], int len)
{
int id=0;
for(int i=0; i<len; i++)
id=id*26+S[i]-'A';
return id;
}
int main()
{
int n,m;
cin >> n >> m;
for(int i=0; i<n; i++)
{
cin >> S[i];
int kb=HashFunc(S[i],3);
HashTable[kb]++;
}
for(int i=0; i<m; i++)
{
cin >> temp;
int kb1=HashFunc(temp,3);
cout << HashTable[kb1] << endl;
}
}