88888888y

导航

 

题目:http://ybt.ssoier.cn:8088/problem_show.php?pid=1456

题目描述:往空书架里存书找书

题目思路:看见字符串堆就可以去找哈希了

正常人的思路一般都是一个一个算哈希值,存书架里,要找的时候再遍历

对嘛,反正n<=30000,搜了也没啥大事

但是,哈希表里面的一个原则是“哈希值相同的字符串大概率相同“,可不是一定

而直接比字符串,30000个又不太现实

于是,我们就想到了下面的玩法

以哈希值为进门钥匙,把值相同的东西放在一起,然后依据每个字符串的哈希值进行存和找

这样的话,计算哈希值就可以帮我们分担一部分时间压力

如果以这个思路往下走的话,那就只能把“vector”请出山了

vector可以被理解为是一个表格,我们这次要用的vector如下

表头(哈希值\字符串) 1号字符串 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 ......
哈希值为1的 ...... ...... ......                                
...... ......                                    
11659 Java ......                                  
...... ......                                    
21827 C# ......                                  

比如要存储C#,它的哈希值为21827,那就把他存在21827那一行里

如果要找C#,它的哈希值为21827,那就从21827那一行里找,找到就出“YES”,没找到就算了

在这里还有一个操作就是把某一行一共多少个东西,数量可以给找出来

一般是用 .size() 来找

上面就是基本思路了,接下来众人请看代码行事

#include<vector>
#include<string>
#include<iostream>
using namespace std;
string t,s;int n;//魔鬼细节
//这里必须用string来导,不然会与vector冲突
//天天净是编译错误,本人在这儿死了三遍 
vector<string> ks[23335];//定义vector 
//vector的表头应该是固定的int
//在<>里面的数据才是决定后面它存的是个什么 
inline void add(){
	int hh=0;//这里的初值别太大就没问题
	//我想定0,1,2,3什么的都可以 
	for(int i=0;s[i];++i){
		if(s[i]==' '){
			continue;//空格可以要着也可以不要
			//如果要要的话,它的ASCII码是32 
		}
		hh=(hh*111*210+s[i])%23333;//算哈希值 
		//魔鬼细节
		//第一个,它必须要对一个质数取余 
		//不然vector吃不下 
		//第二个,它不能直接乘以一个5位数 
		//要分成两个3位数分别成,不然时间会刚好超限 
		//本人在这死了十一遍 
	}
	for(int i=0;i<(int)ks[hh].size();i++){
		//找到这个哈希值代表的行
		//一个一个看 
		if(ks[hh][i]==s){//看到了 
			return;//那还往里存干嘛? 
		}
	}
	//没看到 
	ks[hh].push_back(s);//存进去 
}
inline void find(){
	int hh=0;
	for(int i=0;s[i];++i){
		if(s[i]==' '){
			continue;
		}
		hh=(hh*111*210+s[i])%23333;
	} 
	for(int i=0;i<(int)ks[hh].size();i++){
//由此处向上皆与上文同理 
		if(ks[hh][i]==s){//看到了 
			cout<<"yes"<<endl;//打yes 
			return;
		}
	}
	//没看到 
	cout<<"no"<<endl;//打no 
}
int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;++i){
		cin>>t;//先把指令打进来 
		if(t=="find"){//如果是“寻找” 
			getline(cin,s);
			//把字符串带着空格一起捞进来 
			find();	
		}
		else{//如果是“存入” 
			getline(cin,s);
			add();
			//同理 
		}	
	}
	return 0;
}

总结:注意细节

 

posted on 2022-04-23 11:59  88888888y  阅读(128)  评论(0)    收藏  举报