poj2503查字典 -map或hash

来源:互联网 发布:互普威盾阻止软件安装 编辑:程序博客网 时间:2024/04/29 15:17

这个题目适合做模版题

map:

#include<iostream>#include<map>#include<cstdio>#include<string>using namespace std;int main(){    map<string,string>p;//两种语言的单词对应。    char a[12],b[12];    while(scanf("%s",a))    {        if(getchar()=='\n')break;        cin>>b;        p[b]=a;    }    do{if(p[a]=="")cout<<"eh"<<endl;    else cout<<p[a]<<endl;    }while(cin>>a);        return 0;}

写了个没处理冲突的hash,水过:当然一般情况下不要这么写啦。

#include<iostream>#include<map>#include<string>#include<string.h>#include<stdio.h>using namespace std;const int maxn=1000009,mod=1000007;struct node{string en,fn;int next;}edge[maxn];int head[mod],cnt=0;int hash(string s){int seed=131,key=0,len=s.length();for(int i=0;i<len;i++)key=(key*seed+s[i]-'0')%mod;return key;}int add(string en,string fn){int key=hash(fn);edge[key].fn=fn, edge[key].en=en;return 1;}int main(){string a,b;    while(cin>>a)    {        if(getchar()=='\n')break;        cin>>b;        add(a,b);    }    do{    int t=hash(a);    if(edge[t].fn==a)    cout<<edge[t].en<<endl;    else cout<<"eh"<<endl;        }while(cin>>a);    return 0;}
链式处理冲突:

#include<iostream>#include<map>#include<string>#include<string.h>#include<stdio.h>using namespace std;const int maxn=100009,mod=1000007;struct node{//数据数组,next是链,相当于图的边。string en,fn;int next;}edge[maxn];int head[mod],cnt=0;//head数字,模的头数据,和图的存储是一样的。相当于顶点 int hash(string s){//哈希函数,自己随便来个种子,根据数据范围找个质数模int seed=131,key=0,len=s.length();for(int i=0;i<len;i++)key=(key*seed+s[i]-'0')%mod;return key;}int add(string en,string fn){//记录过程,相当于图的加边操作int key=hash(fn);/*int u=head[key];//判断是否存在过当前关键字 while(u){if(edge[u].fn==fn)return 0;//已经存在,已经插入过u=edge[u].next; }*/edge[++cnt].fn=fn, edge[cnt].en=en;edge[cnt].next=head[key];head[key]=cnt;return 1;}int find(string s){//查找,相当于图遍历,找到某条边int key=hash(s);int u=head[key];while(u){if(edge[u].fn==s)return u;u=edge[u].next;}return 0;}int main(){edge[0].en="eh";string a,b;    while(cin>>a)    {        if(getchar()=='\n')break;        cin>>b;        add(a,b);    }    do{    int t=find(a);    cout<<edge[t].en<<endl;        }while(cin>>a);  return 0;}

开放地址法:

100000的数据范围,先开了个小的mod100007,后果是华丽丽的超时了.改到5倍大小后好了.

#include<iostream>#include<map>#include<string>#include<string.h>#include<stdio.h>using namespace std;const int maxn=500009,mod=500007;struct node{string en,fn;}edge[maxn];int hash(string s){int seed=131,key=0,len=s.length();for(int i=0;i<len;i++)key=(key*seed+s[i]-'0')%mod;return key;}void add(string en,string fn){int key=hash(fn);while(edge[key].fn!=""){//开放地址,自己的空着就用自己的,否则就去找下一个空着的.key++;key%=mod;}edge[key].fn=fn, edge[key].en=en;}int find(string s){int key=hash(s);while(edge[key].fn!=s){if(edge[key].fn=="")return -1;key++;key%=mod;}return key;}int main(){string a,b;    while(cin>>a)    {        if(getchar()=='\n')break;        cin>>b;        add(a,b);    }    do{    int t=find(a);    if(t>=0)cout<<edge[t].en<<endl;    else cout<<"eh"<<endl;        }while(cin>>a);  return 0;}



原创粉丝点击