题目
input
[expelliarmus] the disarming charm
[rictusempra] send a jet of silver light to hit the enemy
[tarantallegra] control the movement of one's legs
[serpensortia] shoot a snake out of the end of one's wand
[lumos] light the wand
[obliviate] the memory charm
[expecto patronum] send a Patronus to the dementors
[accio] the summoning charm
@END@
4
[lumos]
the summoning charm
[arha]
take me to the sky
output
light the wand
accio
what?
what?
思路
- 先处理输入的每一行的[魔法]功能,计算魔法的hash值,用map将hash值和index对应,s1[index]中存储中魔法字符串;计算功能的hash值,用map将hash值和index对应,s2[index]中存储中魔法字符串.
- 查找的时候,先判断是魔法还是功能,再计算hash值,根据hash值找到对应的index,输出对应的功能或者魔法。
注意点
- 由于魔法和功能对应的字符串里都可能有空格,所以我使用getline来存每一行字符串,注意当getline前面出现了cin时,要加一行cin.ignore(),用来忽略回车。
- 当出现@END@说明不用记录魔法和功能了。当输入为@END@时,由于我使用的是getline,所以s里面记录的可能不仅仅是@END@,还会用一下空格,所以要去除里面的空格,在进行判断。
string ss=s;
trim(ss);//去除头、尾空格
if(ss=="@END@") break;
- 计算hash值时,为了避免值过大,会取模,但是在计算seed的x次方时,也要注意取模,它也有可能过大。
- 写pow(int x,int y)//求x的y次方 这个函数时,一定要注意,num的初值是1,和加法不同,乘法一定要置1.
- 注意string的一些函数的用法,查找、截取等。
代码
#include<iostream>
#include<map>
const int mod =1e9+7;
const int seed1 =17;
const int seed2 =131;
const int maxn=1e5+10;
using namespace std;
map<int,int> mp1,mp2;
string s1[maxn],s2[maxn];
unsigned long long pow(int x,int y){//求x的y次方
unsigned long long num=1;//加法和乘法不同,一定要置1
for(int i=0;i<y;i++){
num=num*x;
num=num%mod;//太大了,取模
}
return num;
}
void trim(string &s)//去掉空格
{
if( !s.empty() )
{
s.erase(0,s.find_first_not_of(" "));
s.erase(s.find_last_not_of(" ") + 1);
}
}
int main(){
int index=-1;
while(1){//存储魔咒和功能,并计算hash表,入数组
index++;
string s;
getline(cin,s);//s里面存着的是一行魔法和功能
string ss=s;
trim(ss);//去除头、尾空格
if(ss=="@END@") break;
//处理魔法
int pos1=s.find("[");
int pos2=s.find("]");
unsigned long long hash1=0;
int cnt1=1;
for(int i=pos2-1;i>pos1;i--){
int sh=s[i];//s[i]位置的字符的ASCII码大小
hash1=(sh*pow(seed1,cnt1)+mod+hash1)%mod;
cnt1++;
}
mp1[hash1]=index;
s1[index]=s.substr(pos1+1,pos2-1);
//处理功能
unsigned long long hash2=0;
int cnt2=1;
for(int i=s.length()-1;i>pos2+1;i--){
int sh=s[i];
hash2=(sh*pow(seed2,cnt2)+mod+hash2)%mod;
cnt2++;
}
mp2[hash2]=index;
s2[index]=s.substr(pos2+2,s.length() -1);
}
int n;cin>>n;
cin.ignore() ;
for(int i=0;i<n;i++){
string str;
getline(cin,str);
if(str[0]=='['){//魔咒
unsigned long long hash1=0;
int cnt1=1;
for(int i=str.length() -2;i>0;i--){
int sh=str[i];//s[i]位置的字符的ASCII码大小
hash1=(sh*pow(seed1,cnt1)+hash1+mod)%mod;
cnt1++;
}
map<int, int>::iterator iter=mp1.find(hash1);
if(iter!=mp1.end()){//找到了
cout<<s2[iter->second]<<endl;
}
else{
cout<<"what?"<<endl;
}
}
else{
unsigned long long hash2=0;
int cnt2=1;
for(int i=str.length()-1;i>=0;i--){
int sh=str[i];
hash2=(sh*pow(seed2,cnt2)+hash2+mod)%mod;
cnt2++;
}
map<int, int>::iterator iter=mp2.find(hash2);
if(iter!=mp2.end()){
cout<<s1[iter->second]<<endl;
}
else{
cout<<"what?"<<endl;
}
}
}
}