采用空间换时间的一种方法。
将元素通过一个函数转换为整数,使得该整数尽可能唯一地代表这个元素
问题1:给出N个正整数, 再给出M个数,问这M个数是否在N个数中出现过。
//给出N个正整数, 再给出M个数,问这M个数是否在N个数中出现过。
#include<cstdio>
const int maxn = 100010;
bool hashTable[maxn] = {false};
int main(){
int N, M;
int x;
scanf("%d%d", &N, &M);
for(int i = 0; i < N; i++){
scanf("%d", &x);
hashTable[x] = true;
}
for(int i = 0; i < M; i++){
scanf("%d", &x);
if(hashTable[x] == true)
printf("YES\n");
else
printf("NO\n");
}
return 0;
}
问题2:要求查询M个欲查询的数中每个数在N个数中出现的次数
//要求查询M个欲查询的数中每个数在N个数中出现的次数
#include<cstdio>
const int maxn = 100010;
int hashTable[maxn] = {0};
int main(){
int N, M;
int x;
scanf("%d%d", &N, &M);
for(int i = 0; i < N; i++){
scanf("%d", &x);
hashTable[x]++;
}
for(int i = 0; i < N; i++){
scanf("%d", &x);
printf("%d\n", hashTable[x]);
}
return 0;
}
PAT A1039
对字符串进行哈希映射
#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;
const int maxn = 26*26*26*10+1;
vector <int> stu[maxn];
int getID(char name[]){
int sum = 0;
for(int i = 0; i < 3; i++){
int x = name[i]-'A';
sum = sum*26 + x;
}
sum = sum*10 + (name[3] -'0');
return sum;
}
int main(){
int n, k;
char name[5];
scanf("%d%d", &n, &k);
for(int i = 0; i < k; i++){
int co, m;
scanf("%d%d", &co, &m);
for(int j = 0; j < m; j++){
scanf("%s", name);
int x = getID(name);
stu[x].push_back(co);
}
}
for(int i = 0; i < n; i++){
scanf("%s", name);
int x = getID(name);
printf("%s", name);
printf(" %d", stu[x].size());
sort(stu[x].begin(), stu[x].end());
for(int j = 0; j < stu[x].size(); j++)
printf(" %d", stu[x][j]);
printf("\n");
}
return 0;
}
出现问题:
定义vector时,不要放在主函数内部,否则太大会出现溢出情况。
输入:
由于数据量庞大,不要采用cin, cout进行输入和输出
存储结构:
采用vector进行存储,使用mapstring会超时
如果采用二维数组,最后一组数据会超时
输出:
每一行结尾,不要忘记使用回车
PAT A1047
#include<cstdio>
#include<vector>
#include<cstring>
#include<algorithm>
using namespace std;
vector <int> co[2510];
char name[40010][5];
bool cmp(int a, int b){
return strcmp(name[a], name[b]) < 0;
}
int main(){
int n, k, x, cou, y;
scanf("%d%d", &n, &k);
for(int i = 0; i < n; i++){
scanf("%s", name[i]);
scanf("%d", &x);
for(int j = 0; j < x; j++){
scanf("%d", &cou);
co[cou].push_back(i);
}
}
for(int i = 1; i <= k; i++){
printf("%d %d\n", i, co[i].size());
sort(co[i].begin(), co[i].end(), cmp);
for(int j = 0; j < co[i].size(); j++){
printf("%s\n", name[co[i][j]]);
}
}
return 0;
}
此题并没有用到哈希,主要练习vector
注意点:
刚开始采用vector<char[5]>编译错误
后来采用对学生编号的方法使用vector<int>(根据具体情况,不一定需要对名字字符串进行哈希映射)
使用sort进行排序,对cmp的编写,对int序号进行排序,根据的是两者对应的char名字的字典序
输入:
采用字符串数组,使用scanf("%s", name[i])
存储结构:
char[maxn][5]保存姓名
vector<int> co,保存对应每门课程的学生编号
输出:
遍历每个vector,输出每个对应编号的字符串 printf("%s\n", name[co[i][j]]);
(以上整理参考自《算法笔记》)