题目意思: 给定很多组单词,每一组有两个单词,后面一个单词匹配前面一个单词,现在要求每输入一个单词就去判断是否有对应的单词,有输出对应的单词,否则输出eh
解题思路:
1 哈希表查找
哈希表映射可以比map快很多,还有选择的哈希函数应该尽量满足每一个状态对应一个整数值,这样冲突比较少,但是为了处理冲突, 我么利用链表的思想,将相同key值的状态放在一个链表里面,所以哈希函数的选择很重要,见我的博客就有常见的字符串哈希函数。
大概的思想:每一次读入两个字符数组也就是一下说的状态去求哈希值,然后插人哈希表中,插入的时候是采用往前插,即每一次都要把链表指针往后指,然后更新表头。(哈希表其实就是一个大的数组,得到的哈希值作为数组的下标,然后数组存储的第几个状态这样我么通过“哈希值key-数组-状态”这种思想就可以得到解了)
代码:
#include <algorithm>
#include <iostream>
#include <cstring>
#include <string>
#include <vector>
#include <cstdio>
#include <stack>
#include <queue>
#include <map>
using namespace std;
#define MAXN 1000003//哈希表的长度
typedef char word[25];//定义状态的类型为char数组
word Dic[MAXN] , For[MAXN];//两种不同的状态存放进去,数组的每一个元数就是一个char 数组
int head[MAXN] , next[MAXN];//head是表头,next是链表
char ch[25];
int cnt;//记录第几个状态
//哈希函数
int Hash(char *str)
{
int hash = 0;
while (*str) hash = (*str++) + (hash << 6) + (hash << 16) - hash;
return (hash & 0x7FFFFFFF) % MAXN;
}
//插入哈希表中
void insert_table(int s){
int h = Hash(For[s]);//对For[s]这个状态求哈希值
next[s] = head[h];//将链表往后移动一位
head[h] = s;//插入表头中
}
//哈希映射
int Hash_map(char *str){
int h = Hash(str);
int u = head[h];//从表头开始查找链表
while(u){
if(strcmp(str , For[u]) == 0){//如果找到了直接返回
printf("%s\n" , Dic[u]) ; return 1;
}
u = next[u];//指针指向下一个
}
return 0;
}
int main(){
//freopen("input.txt" , "r" , stdin);
int i , j , flag;
char str[25];
cnt = 1;//不用0,由于被看做不存在
while(gets(ch) && ch[0] != '\0'){
i = j = flag = 0;
for(int k = 0 ; k < strlen(ch) ; k++){
if(ch[k] == ' '){
flag = 1 ; continue;
}
if(!flag){
Dic[cnt][i] = ch[k] ; i++;
}
if(flag){
For[cnt][j] = ch[k] ; j++;
}
}
insert_table(cnt);//插入
cnt++;//这里不要忘了
}
while(gets(str)){
if(!Hash_map(str)) printf("eh\n");
}
}
2 map映射
1 map 由于每组的dictionary都不同可以利用map的性质去映射查找,但是由于map的内部实现是红黑数,加上如果用string做键值,那么处理起来将会很慢,但是代码简单
2 注意判断空格,直接判断ch[0] != '\0';
代码:
#include <algorithm>
#include <iostream>
#include <cstring>
#include <string>
#include <vector>
#include <cstdio>
#include <stack>
#include <queue>
#include <map>
using namespace std;
#define MAXN 100010
map<string , string>m;
string str1 , str2 , str;
char ch[100];
int main(){
//freopen("input.txt" , "r" ,stdin);
m.clear();
int flag , cnt = 1;
while(gets(ch) && ch[0] !='\0'){
str1 = str2 = "" ; flag = 0;
for(int i = 0 ; i < strlen(ch) ; i++){
if(ch[i] == ' ') { flag = 1 ; continue;}
if(flag) str2 += ch[i];
if(!flag) str1 += ch[i];
}
m[str2] = str1;//插入
}
while(cin>>str){
if(m[str] != "") cout<<m[str]<<endl;
else printf("eh\n");
}
return 0;
}