散列

例:给出N个正整数,再给出M个正整数,问这M个数中的每个数分别是否在N个数中出现过

思路一:对每个要查询的正整数x,遍历所有n个数,看是否有一个数与x相等

思路二:用空间换时间,设定一个bool型数组hashTable,其中hashTable[x]==true表示正整数x在N个正整数中出现过,而hashTable[x]==false表示正整数x在N个正整数中没有出现过,这样就可以在一开始读入N个正整数时就进行预处理,即当读入的数为x时,就令hashTable[x]=true,于是对M个欲查询的数,直接通过hashTable数组判断出每个数是否出现过,时间复杂度为O(N+M),代码:

#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(N+M)的时间复杂度输入每个与查询的数出现的次数,代码:

#include<iostream>
const int maxn=100010;
int hashTable[maxn]={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;
}

 例题:给出N个字符串,再给出M个查询字符串,问每个查询字符串在N个字符串中出现的次数

#include<iostream>
using namespace std;
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;
}

 

posted @ 2020-08-08 09:15  Heinrich♣  阅读(107)  评论(0编辑  收藏  举报