散列

先看一个简单的问题:给出N个正整数,再给出M个正整数,问这M个数中的每一个数是否在N个数中出现过,其中,N,M<=105,且所有正整数都不超过105.时间复杂度为O(M+N).

#include<cstdio>
const int maxn = 100010;
bool hashTable[maxn] = false;
int main(){
 int n,m,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;
}

如果题目要求M个欲查询的数中每个数在N个数中出现的次数,那么可以把hashTable数组替换为int型,然后在输入N个数时进行预处理,即当输入的数为x时,就令hashTable[x]++,这样就可以达到O(M+N)复杂度。

#include<cstdio>
const int max = 100010;
bool hashTable[max] = {0};
int main(){
 int n,m,x;
 scanf("%d%d",&n,&m);
 for(int i = 0;i<n;i++){
  scanf("%d",&x); 
  hashTable[x]++;
 } 
 for(int i = 0;i<m;i++){
  scanf("%d",&x);
  printf("%d\n",hashTable[x]);
 }
 return 0;
}

上面的两个问题都有一个特点,那就是直接把输入的数作为数组的下标来对这个数的性质进行统计。如果key不是整数,那么又应当如何设计散列函数呢?

将字符串映射为一个整数

int hashFunc(char S[],int len){
 int id = 0;
 for(int i = 0;i<len;i++){
  id = id*26 +(S[i]-'A');
 }
 return id;
} 

以一个问题结尾,给出N个字符串(由恰好三位大写字母组成),再给出M个查询字符串,问每个查询字符串在N个字符串中出现的次数。

#include<cstdio>
const int maxn = 100;
char S[maxn][5],temp[5];
int hashTable[26*26*26+10]; 

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;
 scanf("%d%d",&n,&m);
 for(int i = 0;i<n;i++){
  scanf("%s",S[i]);
  int id = hashFunc(S[i],3);
  hashTable[id]++;
 }
 for(int i = 0;i<m;i++){
  scanf("%s",temp);
  int id = hashFunc(temp,3);
  printf("%d\n",hashTable[id]);
 }
 return 0;
 }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值