zoukankan      html  css  js  c++  java
  • Aizu

    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]!='';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]!='';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;
    }

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


    作者:孙建钊
    出处:http://www.cnblogs.com/sunjianzhao/
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

  • 相关阅读:
    eclipse中jdk源码调试步骤
    [POJ2777] Count Color
    [HNOI2004] L语言
    [USACO08DEC] 秘密消息Secret Message
    The XOR Largest Pair [Trie]
    前缀统计 [Trie]
    于是他错误的点名开始了 [Trie]
    Palindrome [Manecher]
    兔子与兔子 [Hash]
    [CF985F] Isomorphic Strings
  • 原文地址:https://www.cnblogs.com/sunjianzhao/p/11350414.html
Copyright © 2011-2022 走看看