Aizu - ALDS1_4_C Dictionary

Search III

Your task is to write a program of a simple dictionary which implements the following instructions:

  • insert str: insert a string str in to the dictionary
  • find str: if the distionary contains str, then print 'yes', otherwise print 'no'

Input

In the first line n, the number of instructions is given. In the following n lines, n instructions are given in the above mentioned format.

Output

Print yes or no for each find instruction in a line.

Constraints

  • A string consists of 'A', 'C', 'G', or 'T'
  • 1 ≤ length of a string ≤ 12
  • n ≤ 1000000

Sample Input 1

5
insert A
insert T
insert C
find G
find A

Sample Output 1

no
yes

Sample Input 2

13
insert AAA
insert AAC
insert AGA
insert AGG
insert TTT
find AAA
find CCC
find CCC
insert CCC
find CCC
insert T
find TTT
find T

Sample Output 2

yes
no
no
yes
yes
yes

做这道题用散列查找,但是我写的第一个开放地址法,显示超时,于是我又用链地址进行求解,最后通过AC,毕竟链地址对于冲突的出现非常少,但是也因为链地址的实现比较复杂容易出错
(毕竟是使用指针来实现的),所以首选不会使用链地址,但不可否认的是链地址的确效率很高。
链地址AC代码:

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<malloc.h>
using namespace std;
const int maxn=1e6+10;
const int MAX=999983;
long long int zhuanhuan(char s[]);
struct node
{
long long int b;
struct node *p;
}a[maxn];
int main()
{
int n;
for(int i=0;i<maxn;i++)
a[maxn].b=0,a[maxn].p=NULL;
char str1[10],str2[20];
cin>>n;
while(n--)
{
scanf("%s%s",str1,str2);
long long int u=zhuanhuan(str2);
int m=u%MAX;
if(strcmp(str1,"insert")==0)
{
struct node *next=a[m].p;
if(a[m].b==0) a[m].b=u,a[m].p=(struct node *)malloc(sizeof(struct node)),a[m].p->b=0,a[m].p->p=NULL;
else
{
while(1)
{

if(next->b==0)
{
next->b=u;
next->p=(struct node *)malloc(sizeof(struct node));
next->p->b=0;
next->p->p=NULL;
break;
}
else next=next->p;
}
}
}
else
{
if(a[m].b==u) cout<<"yes"<<endl;
else
{
if(a[m].p==NULL) cout<<"no"<<endl;
else
{
struct node *next=a[m].p;
while(1)
{
if(next->b==u) {cout<<"yes"<<endl;break;}
else
{
if(next->p==NULL)
{
cout<<"no"<<endl;
break;
}
else next=next->p;
}
}
}
}
}
}
return 0;
}

long long int zhuanhuan(char s[])
{
long long int sum=0;
for(int i=0;s[i]!='\0';i++)
{
switch(s[i])
{
case 'A':sum+=1*pow(10,i);break;
case 'G':sum+=2*pow(10,i);break;
case 'C':sum+=3*pow(10,i);break;
case 'T':sum+=4*pow(10,i);break;
}
}
return sum;
}

到了第二天,还是不死心,仍旧想除链地址外的其他方法做出,因为我认为只要散列函数写得好,应该可以做出,可以不超时。但即便用再散列函数法,依旧还不行。但皇天不负有心人,最终让我AC了,但是在第一天的基础上仅仅改了一个地方,让我非常的无奈,为什么一开始就没有想到,现附上AC代码,并在改的地方加上注释:

#include<iostream>
#include<cstring>
#include<cmath>
#include<cstdio>
using namespace std;
const int maxn=1e6+10;
const int MAX=999983;
long long int zhuanhua(char s[]);
int main()
{
long long int a[maxn],n;
char str1[10],str2[15];
cin>>n;
while(n--)
{
scanf("%s%s",str1,str2);
long long int sum=zhuanhua(str2);
int m=sum%MAX;
int s=0;
if(str1[0]=='i')
{
int i=0;
do
{
if(a[(m+i)%MAX]==0)
{
a[(m+i)%MAX]=sum;
break;
}
if(a[(m+i)%MAX]==sum) break; //这句话在insert中遇到极端情况(有许多insert都是一样的时候)可以很大效率上减少冲突
} while(++i);
if(i>s) s=i;
}
else
{
int i=0;
do
{
if(a[(m+i)%MAX]==0)
{
cout<<"no"<<endl;
break;
}
if(a[(m+i)%MAX]==sum)
{
cout<<"yes"<<endl;
break;
}
}while(++i);
}
}
return 0;
}

long long int zhuanhua(char s[])
{
long long int sum=0;
for(int i=0;s[i]!='\0';i++)
{
switch(s[i])
{
case 'A':sum+=1*pow(5,i);break;                             //我本人认为这里的算法应该是使得对应的值唯一,可是我自己没有将其进行数理逻辑证明
case 'G':sum+=2*pow(5,i);break;
case 'C':sum+=3*pow(5,i);break;
case 'T':sum+=4*pow(5,i);break;
}
}
//cout<<sum<<endl;
return sum;
}

 

散列法属于一种搜索 存储的算法,利用个元素的值确定存储位置,于是也会利用个元素的值进行搜索。

转载于:https://www.cnblogs.com/sunjianzhao/p/11350414.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值