【PAT笔记】PAT中的散列思想

散列的介绍

散列(hash)是常用的算法思想之一,在很多程序上都会有意无意的使用到。用一句话来概括散列思想的话就是:“将元素通过一个函数转换为整数,使得该整数可以尽量唯一地代表这个元素”。其中把转换函数称为散列函数H。

那么对key是整数来说,有哪些常用的散列函数呢?一般来说,常见的散列函数有直接定址法、平方取中法、除留余数法,其中直接定址法是指恒等变换(即H(key)=key,很多问题都是直接把key作为数组下标,是最常见最实用的散列应用)。

散列的适用情形

那么,什么情况下使用散列思想呢?如何在竞赛或者考试中联想到散列思想呢?

  1. 在使用散列思想时,题目一般会给出两个字符串或者两个数组,这两个字符串或者的元素之间存在ans=S1-S2的类似关系;
  2. 题目用于其中某个字符串查询另一个字符串中的元素的情形;

散列的运用

下面给出一些散列思想的运用。

【PAT】B1039 

#include <stdio.h>
#include <string.h>
int main(){
	char hashTable[1010]={0};
	char str1[1010],str2[1010]; 
	int sum=0;
	gets(str1);
	gets(str2);
	int len_a=strlen(str1);
	int len_b=strlen(str2);
	for(int i=0;i<len_a;i++){  //数组的下标是珠子颜色的代表字符,统计每种颜色各有多少个珠子
		hashTable[str1[i]]++; 
	}
	for(int i=0;i<len_b;i++){  //统计完毕后,将需要得到的珠子减去原有的珠子,若出现负数,则表                            示某种颜色的珠子少于需求
		hashTable[str2[i]]--;
	}
	for(int i=0;i<len_b;i++){
		if(hashTable[str2[i]]<0){
			sum=sum+hashTable[str2[i]];
			hashTable[str2[i]]=0;
		}
	}

	if(sum<0) printf("No %d",0-sum);
	else printf("Yes %d",len_a-len_b);
	return 0;
} 

【PAT】B1042

#include <stdio.h>
#include <string.h>
int main(){
	int HashTable[256]={0};
	int k=0,len;
	char str[1010],j;
	gets(str);
	len=strlen(str);
	for(int i=0;i<len;i++){
		if(str[i]>='A'&&str[i]<='Z'){
			HashTable[str[i]-'A']++;  //将标记字符转化为唯一字符表示,这适用于字符串中给出大小写,但实际不需要区分大小写的情况
		}
		else if(str[i]>='a'&&str[i]<='z'){
			HashTable[str[i]-'a']++;
		}
		else 
			HashTable[str[i]]=0;
	}
	for(int i=0;i<26;i++){
		if(HashTable[i]>HashTable[k]){
			k=i;
		}
	}
	printf("%c %d\n",'a'+k,HashTable[k]);
	return 0;
}

【PAT】A1048

#include <stdio.h>
#include <iostream>
#include <algorithm>
using namespace std;
int main(){
	int n,m,a;
	int hashtable[1005]={0};
	scanf("%d%d",&n,&m);
	for(int i=0;i<n;i++){
		scanf("%d",&a);
		++hashtable[a];  //将输入的数字作为数组的下标存储起来,把数组+下标的组合来存放该下标(即数字)的个数
	}
	for(int i=1;i<m;i++){
		if(hashtable[i]&&hashtable[m-i]){
			if(i==m-i&&hashtable[i]<=1){
				continue;
			}
			printf("%d %d\n",i,m-i);
			return 0;
		}
	}
	printf("No Solution\n");
	return 0;
} 

 

综    述

使用散列表示的方式一般有:

  1. 以数组的下标作为记录该数字的存在与否(通过int hashtable[maxn]={0}或者bool hashtable[maxn]={false});
  2. 以数组的下标作为改为字符记录;
  3. 以数组的下标和数组本身结合,记录下标(即数字或者字符)出现的次数(如hashtable[3]=2,hashtable['P']=3分别表示3出现了2次,字符P出现了3次)。

看到题目后应结合题目具体分析寻找最简单的解法。 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_之桐_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值