题目意思: 给定很多组单词,每一组有两个单词,后面一个单词匹配前面一个单词,现在要求每输入一个单词就去判断是否有对应的单词,有输出对应的单词,否则输出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; }