一个简单的问题:给出N个正整数,再给出M个正整数,问这M个数中的每个数分别是否在N个数中出现,其中N,M<=105,且所有正整数不超过105。
现在来思考一下使用暴力遍历的复杂度。
对M个数中的每一个数需要进行N此对比,则时间复杂度为O(NM)。
那如果使用hash表来表示呢?
建立一个hash表,bool hash[maxn],令其中所有值全为false,再输入N的每一个值(设为x),令hash[x]==true,再输入每一个M的值(设为y),则可知每个hash[y]都有一个bool值,若为true,则证明有相同值。打印所有为true的值即可。
#include<cstdio>
const int MAXN 10010
bool hashTable[MAXN]={false};
int main
{
int n,m,x;
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;
}
字符串hash初步
如果key不是整数,那么又该如果设计散列函数呢?
eg:如何将一个二维整点P的坐标映射为一个整数,使得整点P可以由该整数唯一地代表。
P(x,y),0<=x,y<=Range。表示方法有很多,只要能一一对应就可以。
可以令
H( P)=x*Range+y,
每一个字符都有对应的ASCII码,所以可以表示成一个对应的数。
下面来看一个题:
PAT B1029/A1084 旧键盘
题目描述:
旧键盘上有几个键损坏了——在输入一段文字时,对应的字符不会出现。现在给出应该输入的一段文字以及被输入的文字,请列出那些肯定坏掉的键。
输入格式
在两行中分别给出应该输入的文字以及实际被输入的文字。每段文字时不超过80个字符的串,由字母A~Z(包括大小写)、数字0-9以及下划线_(代表空格)组成。题目保证两个字符串均非空。
输出格式:
按照发现顺序,在一行中输出坏掉的键,其中英文字母只输出大写,每个坏键只输出一次。题目保证至少有一个坏键。
比较输入与输出之间差了哪些值(用hash表),去掉重复部分,将小写转换为大写,并用一个数列记录这些值同时输出。
是一个字符与数字混合的串。怎么构建hash表呢?
先考虑暴力解法;
两个字符数组A[80],B[80]分别代表应该输入的值和实际输入的值,逐个对比。
具体逻辑可以看下图(我是懒狗)
利用hash表可以记录本需要重复对比的值,省略重复的步骤
如何设置hashtable的值呢?只能是给每个键位一个值,每一个按键的ASCII码都是不同的。ACSII码最大为256,可以包含所有键位。
可以设置 bool hashtable[256] = {true} ,默认全部键位都可用。
接下来进行遍历比对,将理想输入与实际输入进行比对,将得到的信息记录进hash表。
#define _CRT_SECURE_NO_WARNINGS
#include<cstdio>
#include<iostream>
#include<string>
#define MAXN 10010
using namespace std;
int main()
{
bool hashtable[256];
char ideal_Input[]="This_is_TucK";
char actual_Input[]="is_is_ucK";
int ideal_len, actual_len;
memset(hashtable, true, sizeof(hashtable));
//Input
/*printf("enter idealinput\n");
scanf("%c", ideal_Input);
printf("enter actualinput\n");
scanf("%c",actual_Input);*/
/**/
ideal_len = strlen(ideal_Input);
actual_len = strlen(actual_Input);
//Compare
int j = 0; int temp = 0;
for (int i = 0; i < ideal_len; i++)
{
j = temp;
if (hashtable[ideal_Input[i]] == false)
{
continue;
}
if (ideal_Input[i] == actual_Input[j])
{
temp++;
}
if (ideal_Input[i] != actual_Input[j])
{
//需要考虑大小写,全部转化为大写
if ('a' <= ideal_Input[i]&& ideal_Input[i] <= 'z')
{
int caps;
caps = ideal_Input[i] +'A'-'a';
printf("%c", ideal_Input[i] + 'A' - 'a');
hashtable[ideal_Input[i]] = false;
hashtable[ideal_Input[i] + 'A' - 'a'] = false;
}
else
{
hashtable[ideal_Input[i]] = false;
printf("%c", ideal_Input[i]);
}
}
}
/**/
return 1;
}
上边代码是我自己写的题解,测试过是能用的。