整数散列与字符串hash初步

一个简单的问题:给出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;
}

上边代码是我自己写的题解,测试过是能用的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值