POJ 2503 字符串(两种方法)

本文介绍两种高效字典查询方法:一是利用qsort和二分查找,对字典进行排序后快速定位;二是采用ELF hash函数结合链表解决冲突,实现快速查找。两种方法均针对外语词汇查询场景,通过预处理提高查询效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

   方法一:

          qsort+二分查找。先对字典根据外语来进行qsort.然后通过二分查找即可找到匹配的项。这里用到两个函数sscanf()和bsearch();

#include <iostream>
#include <fstream>
#include <string>
using namespace std;

char str1[11],str2[11];
char str[25];

struct dict{
char en[11];
char fn[11];
}a[100005];

int q_cmp(const void*a,const void*b)
{
return strcmp(((dict*)a)->fn,((dict*)b)->fn);
}

int b_cmp(const void *a,const void *b)
{
return strcmp((char*)a,((dict*)b)->fn);
}

int main()
{
freopen("acm.txt","r",stdin);
int i=0;
int sign=1;
dict *p;
while(gets(str))
{

if(str[0]=='\0')
{
sign=0;
qsort(a,i,sizeof(dict),q_cmp);
continue;
}
if(sign)
{
sscanf(str,"%s %s",a[i].en,a[i].fn);
i++;
}
else
{
p=(dict*)bsearch(str,a,i,sizeof(dict),b_cmp);
if(p)
{
puts(p->en);
}
else
{
puts("eh");
}
}
}
return 0;
}


方法二: 通过ELFhash函数来做。冲突处理则是用到链表的方法。也不难。

#include <iostream>
#include <fstream>
#include <string.h>

#define N 100001
#define strSize 15

using namespace std;

struct hash{
bool used;
char fn[strSize],en[strSize];
hash* next; //用于冲突时构造链表
hash(){used=false; next=NULL;}
hash(char *f,char *e)
{
strcpy(fn,f);
strcpy(en,e);
used=false;
next=NULL;
}
}h[N];

int ELFhash(char *key){

unsigned long h=0;
unsigned long x=0;

while(*key)
{
h=(h<<4)+(*key++); //h左移4位,当前字符ASCII存入h的低四位
if( (x=h & 0xF0000000L)!=0)
{ //如果最高位不为0,则说明字符多余7个,如果不处理,再加第九个字符时,第一个字符会被移出
//因此要有如下处理
h^=(x>>24);
//清空28~31位
h&=~x;
}
}
return h % N;
}


int main()
{
freopen("acm.txt","r",stdin);
char str[30],en[strSize],fn[strSize];
hash* p;
int sign=1,key;

while(gets(str))
{
if(str[0]=='\0')
{
sign=0;
continue;
}
if(sign) //输入字典
{
sscanf(str,"%s %s",&en,&fn);
key=ELFhash(fn); //获取hash值
if(!h[key].used) //对应到hash表中
{
h[key].used=true;
strcpy(h[key].en,en);
strcpy(h[key].fn,fn);
}
else //处理冲突
{
p=&h[key];
while(p->next != NULL) p=p->next;
p->next=new hash(fn,en);
}

}
else //输入外文
{
key=ELFhash(str);
if(!h[key].used) printf("eh\n");
else
{
p=&h[key];
while(p!=NULL)
{
if(!strcmp(str,p->fn))
{
printf("%s\n",p->en);
break;
}
else
{
p=p->next;
}
}
if(p==NULL) printf("eh\n"); //不匹配的情况,不能少
}

}

}
return 0;
}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值