POJ2503三种解法:map+快速排序+二分查找与哈希表
题意很简单:就像查找一本字典,根据输入的条目和要查询的单词,给出查询结果(每个单词长度不超过10)。这题有很多实现方式,最容易想到的就是map,但这是acm训练且stl里面的map速度不够快,那就要另谋出路。
解题思路:
水题,输入时顺便用STL的map标记外语是否出现过,然后再用map建立“外语à英语”的映射,那么输出时先查找“出现”的标记,若有出现过,再输出映射,否则输出“eh”。
法一:Map
用STL毫无难度(要真说难,也就是空行的处理有一点技巧),也可以用hash做,不过比较麻烦
#include<iostream> #include<cstring> #include<string> #include<map> #include<stdio.h> using namespace std; int main() { map<string,string> dic; char str[30],str1[12],str2[12]; while(gets(str)) { if(strlen(str)==0) { break; } sscanf(str,"%s %s",str1,str2); dic[str2] = str1; } string str3,out; while(cin>>str3) { out = dic[str3]; if(out.length()==0) cout<<"eh"<<endl; else cout<<out<<endl; } return 0; }
法二:结构体数组
数据量为100,000。可以想到的是快排+二分,复杂度是O(nlog2n)。还有就是哈希,哈希查询时间是O(1),当然,还要考虑哈希冲突,设计合理的字符串哈希函数。
首先是快排+二分,比较简单。
#include <iostream> using namespace std; const int MAX = 100001; typedef struct { char e[11]; char f[11]; }Entry; Entry entry[MAX]; int cmp(const void *a, const void *b) { return strcmp((*(Entry *)a).f, (*(Entry *)b).f); } //二分查找 int BinSearch(char c[],int len) { int low = 0, high = len - 1; int mid, t; while(low <= high) { mid = (low + high) / 2; t = strcmp(entry[mid].f, c); if(t == 0) return mid; else if(t == -1) low = mid + 1; else high = mid - 1; } return -1; } //相同的单词会有多个,有待优化 int main() { char str[25]; int index = -1; int i = 0; //词典总条数 while(gets(str)) { //是否是空行 //if(str[0] == '\0')// 也可以通过判断长度是否为0 if(strlen(str)==0) break; sscanf(str,"%s %s",entry[i].e,entry[i].f); i++; } //排序 qsort(entry,i,sizeof(Entry),cmp); while(gets(str)) { index = BinSearch(str,i); if(index == -1) printf("eh\n"); else printf("%s\n",entry[index].e); } return 0; }
法三:结构体数组+hash
对于字符串的哈希,在《算法艺术与信息学竞赛》推荐使用ELFHash函数。对于哈希冲突的处理,采用的是链表法(个人认为线性探测等效率不是很高)。
#include <iostream>
const int M = 149993;
typedef struct
{
char e[11];
char f[11];
int next;
}Entry;
Entry entry[M];
int i = 1; //词典总条数
int hashIndex[M];
int ELFHash(char *key)
{
unsigned long h=0;
while(*key)
{
h=(h<<4)+(*key++);
unsigned long g=h&0Xf0000000L;
if(g) h^=g>>24;
h&=~g;
}
return h%M;
}
void find(char f[])
{
int hash = ELFHash(f);
for(int k = hashIndex[hash]; k; k = entry[k].next)
{
if(strcmp(f, entry[k].f) == 0)
{
printf("%s\n",entry[k].e);
return;
}
}
printf("eh\n");
}
int main()
{
char str[22];
while(gets(str))
{
if(str[0] == '\0')
break;
sscanf(str,"%s %s",entry[i].e,entry[i].f);
int hash = ELFHash(entry[i].f);
entry[i].next = hashIndex[hash];
hashIndex[hash] = i;
i++;
}
while(gets(str))
find(str);
return 0;
}
作者:sam
出处:http://www.cnblogs.com/samjustin/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。