题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1880
题意:题目很简单,就不说了啦.
个人感想:
一直都看不懂哈希,也没接触过哈希,最近就练习一下哈希,反正有点时间,我就搞搞以前的想学得算法,免得以后一问3不知。
其实哈希也不是很难,主要他有一个思想就是f(key)=value,key和value一一对应.那么哈希算法就有很多种版本了,我现在用的是BKDRhash,网上的评价也不错,这个主要是通过研究来证明这个哈希的高效。
不管哪个哈希,都会有冲突的时候,那么解决冲突的一个办法,是建立链表,在相同key值下的做成链表,那么可以很容易查到对应的值了,而且有人会说,对于任意字符串,肯定会出现就在一个key值位置.那么这个链表就很大了,那不就没用了。
其实我也这样想过,但是通过随机出来的字符串平均分布,就这个算法比较好了…他分散的字符串很平均,总的来说也会比一个一个比较还要好吧…这是通过测试来得出的结论.更高效的哈希,再看看咯…
分析:哈希算法
代码:
/* Author:GavinjouElephant
* Title:
* Number:
* main meanning:
*
*
*
*/
#include <iostream>
using namespace std;
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <sstream>
#include <cctype>
#include <vector>
#include <set>
#include <cstdlib>
#include <map>
#include <queue>
//#include<initializer_list>
//#include <windows.h>
//#include <fstream>
//#include <conio.h>
#define MaxN 0x7fffffff
#define MinN -0x7fffffff
#define lson 2*k
#define rson 2*k+1
typedef long long ll;
const int INF=0x3f3f3f3f;
const int maxn=1e5+10;
const int mod=100007;
int Scan()//读入整数外挂.
{
int res = 0, ch, flag = 0;
if((ch = getchar()) == '-') //判断正负
flag = 1;
else if(ch >= '0' && ch <= '9') //得到完整的数
res = ch - '0';
while((ch = getchar()) >= '0' && ch <= '9' )
res = res * 10 + ch - '0';
return flag ? -res : res;
}
void Out(int a) //输出外挂
{
if(a>9)
Out(a/10);
putchar(a%10+'0');
}
struct Node
{
char key[25];
char ans[85];
int nex;
};
Node nodeA[maxn],nodeB[maxn];
int topA;
int topB;
int headA[maxn];
int headB[maxn];
void init()
{
topA=0;
topB=0;
memset(headA,-1,sizeof(headA));
memset(headB,-1,sizeof(headB));
}
unsigned int BKDRhash(char* str)
{
unsigned int seed=131;
unsigned int hash1=0;
while(*str)
{
hash1=hash1*seed + *str++;
}
return (hash1 & 0x7fffffff) % mod;
}
void inserthash(char * key,char * ans)
{
unsigned int h;
h=BKDRhash(key);
strcpy(nodeA[topA].key,key);
strcpy(nodeA[topA].ans,ans);
nodeA[topA].nex=headA[h];
headA[h]=topA;
topA++;
h=BKDRhash(ans);
strcpy(nodeB[topB].key,key);
strcpy(nodeB[topB].ans,ans);
nodeB[topB].nex=headB[h];
headB[h]=topB;
topB++;
}
char * searchhash(char * key ,int on)
{
unsigned int h=BKDRhash(key);
if(on==1)
{
for(int i=headA[h];i!=-1;i=nodeA[i].nex)
{
if(strcmp(nodeA[i].key,key)== 0)
{
return nodeA[i].ans;
}
}
}
else
{
for(int i=headB[h];i!=-1;i=nodeB[i].nex)
{
if(strcmp(nodeB[i].ans,key)==0)
{
return nodeB[i].key;
}
}
}
return "what?";
}
string str;
char que[25];
char ans[85];
char query[120];
int main()
{
#ifndef ONLINE_JUDGE
freopen("coco.txt","r",stdin);
freopen("lala.txt","w",stdout);
#endif
init();
while(getline(cin,str))
{
if(str[0] == '@' )break;
int len=0;
int i;
for(i=1;str[i]!=']';i++)
{
que[len++]=str[i];
}
que[len]='\0';
i+=2;
len=0;
for(;str[i]!='\0';i++)
{
ans[len++]=str[i];
}
ans[len]='\0';
inserthash(que,ans);
}
int n;
scanf("%d",&n);
getchar();
while(n--)
{
getline(cin,str);
if(str[0]=='[')
{
int len=0;
for(int i=1;str[i]!=']';i++)
{
query[len++]=str[i];
}
query[len]='\0';
printf("%s\n",searchhash(query,1));
}
else
{
int len=0;
for(int i=0;str[i]!='\0';i++)
{
query[len++]=str[i];
}
query[len]='\0';
printf("%s\n",searchhash(query,-1));
}
}
return 0;
}