哈希

采用空间换时间的一种方法。

将元素通过一个函数转换为整数,使得该整数尽可能唯一地代表这个元素

 

问题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]]);

 

(以上整理参考自《算法笔记》)

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值