《算法笔记》第4章 入门篇(2)—算法初步
4.2散列
4.2.1散列的定义与整数散列
1.O_O
给出N个正整数,再给出M个正整数,问这M个数中的每个数分别是否在N个数中出现过,其中N,M<=10^5,且所有
正整数均不超过10^5。例如N=5,M=3,N个正整数为{8,3,7,6,2},欲查询的M个正整数为{7,4,2},于是后者中
只有7和2在N个正整数中出现过,而4是没有出现过的。
代码如下:
//用空间换时间
#include<cstdio>
using namespace std;
//因为N<=10^5=100000,所以maxn可以为100010
const int maxn = 100010;//maxn表示数组的长度
//数组hashTable用于记录欲查询数x是否出现过
bool hashTable[maxn] = {false};//默认N个正整数均未出现过
int main(){
int n;//n表示N个正整数
int m;//m表示M个正整数
int x;//x表示欲查询数
scanf("%d %d", &n, &m);//输入n和m
//通过循环输入N个正整数
for(int i = 0; i < n; i++){
scanf("%d", &x);//输入x
hashTable[x] = true;//表示欲查询数x出现过
}
//通过循环输入M个正整数
for(int j = 0; j < m; j++){
scanf("%d", &x);//输入x
//判断欲查询数x是否已经出现过
if(hashTable[x] == true){//x出现过
printf("%d在N个正整数中出现过\n", x);
}else{//x未出现过
printf("%d在N个正整数中未出现过\n", x);
}
}
return 0;
}
运行结果如下:
2.O_O
将上一题的要求改为:
求M个欲查询的数中每个数在N个数中出现的次数,其他条件不变。
代码如下:
#include<cstdio>
using namespace std;
//因为N<=10^5=100000,所以maxn可以为100010
const int maxn = 100010;//maxn表示数组的长度
//数组hashTable用于记录欲查询数x出现的次数
int hashTable[maxn] = {0};//默认N个正整数出现次数均为0
int main(){
int n;//n表示N个正整数
int m;//m表示M个正整数
int x;//x表示欲查询数
scanf("%d %d", &n, &m);//输入n和m
//通过循环输入N个正整数
for(int i = 0; i < n; i++){
scanf("%d", &x);//输入x
hashTable[x]++;//表示欲查询数x的出现次数自增1
}
//通过循环输入M个正整数
for(int j = 0; j < m; j++){
scanf("%d", &x);//输入x
//输出正整数x在N个正整数中的出现次数
printf("%d的出现次数为:%d\n", x, hashTable[x]);
}
return 0;
}
运行结果如下:
4.2.2字符串hash初步
给出N个字符串(由恰好三位大写字母组成),再给出M个查询字符串,
问每个查询字符串在N个字符串中出现的次数。
代码如下:
#include<cstdio>
using namespace std;
const int maxn = 100;//maxn表示存储N个字符串的数组的一维长度
//数组S用于存储输入的N个字符串;
//数组temp用于存储输入的M个字符串中的单个字符串。
//因为题目要求字符串恰好由三位大写字母组成,所以数组S的二维
//长度和数组temp的一维长度均可为5。
char S[maxn][5], temp[5];
//因为字符串恰好由三位大写字母组成,即len=3,且字符串能够映射
//的最大整数为26^len-1,即26^3-1,所以数组hashTable的长度可以为26*26*26+10
int hashTable[26*26*26+10];
//函数hashFunc用于将字符串映射为十进制整数
int hashFunc(char S[], int len){
int id = 0;
//通过循环实现将字符串映射的二十六进制整数转换为十进制整数
for(int i = 0; i < len; i++){
//操作(S[i]-'A')可将单个字符映射为[0,25]范围内的唯一二十六进制整数
id = id*26 + (S[i] - 'A');
}
return id;
}
int main(){
int n, m;//n的范围为:n<=100
scanf("%d %d", &n, &m);//输入n和m
//通过循环输入N个字符串
for(int i = 0; i < n; i++){
scanf("%s", S[i]);//输入单个字符串
int id = hashFunc(S[i], 3);//将输入的字符串映射为十进制整数并赋值给id
hashTable[id]++;//输入的字符串出现的次数自增1
}
//通过循环输入M个查询字符串
for(int i = 0; i < m; i++){
scanf("%s", temp);//输入单个字符串
int id = hashFunc(temp, 3);将输入的查询字符串映射为十进制整数并赋值给id
//输出该查询字符串在N个字符串中出现的次数
printf("%s的出现次数为:%d\n", temp, hashTable[id]);
}
return 0;
}
运行结果如下:
参考资料如下:
[1] 胡凡,曾磊.算法笔记[M].北京:机械工业出版社,2022:85-98.
[2] codeup网址:http://codeup.hustoj.com
[3] PAT网址:https://www.patest.cn/practice