『HDU 1880』魔咒词典

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1880

题意:题目很简单,就不说了啦.

个人感想:
一直都看不懂哈希,也没接触过哈希,最近就练习一下哈希,反正有点时间,我就搞搞以前的想学得算法,免得以后一问3不知。
其实
哈希
也不是很难,主要他有一个思想就是f(key)=valuekey和value一一对应.那么哈希算法就有很多种版本了,我现在用的是BKDRhash,网上的评价也不错,这个主要是通过研究来证明这个哈希的高效
不管哪个哈希,都会有冲突的时候,那么解决冲突的一个办法,是建立链表,在相同key值下的做成链表,那么可以很容易查到对应的值了,而且有人会说,对于任意字符串,肯定会出现就在一个key值位置.那么这个链表就很大了,那不就没用了。
其实我也这样想过,但是通过
随机出来的字符串平均分布
,就这个算法比较好了…他分散的字符串很平均,总的来说也会比一个一个比较还要好吧…这是通过测试来得出的结论.更高效的哈希,再看看咯…

分析:哈希算法

代码:

/* Author:GavinjouElephant
 * Title:
 * Number:
 * main meanning:
 *
 *
 *
 */


#include <iostream>
using namespace std;
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <sstream>
#include <cctype>
#include <vector>
#include <set>
#include <cstdlib>
#include <map>
#include <queue>
//#include<initializer_list>
//#include <windows.h>
//#include <fstream>
//#include <conio.h>
#define MaxN 0x7fffffff
#define MinN -0x7fffffff
#define lson 2*k
#define rson 2*k+1
typedef long long ll;
const int INF=0x3f3f3f3f;
const int maxn=1e5+10;
const int mod=100007;
int Scan()//读入整数外挂.
{
    int res = 0, ch, flag = 0;

    if((ch = getchar()) == '-')             //判断正负
        flag = 1;

    else if(ch >= '0' && ch <= '9')           //得到完整的数
        res = ch - '0';
    while((ch = getchar()) >= '0' && ch <= '9' )
        res = res * 10 + ch - '0';
    return flag ? -res : res;
}
 void Out(int a)    //输出外挂
 {
     if(a>9)
         Out(a/10);
     putchar(a%10+'0');
 }

 struct Node
 {
     char key[25];
     char ans[85];
     int nex;
 };


 Node  nodeA[maxn],nodeB[maxn];

 int topA;
 int topB;

 int headA[maxn];
 int headB[maxn];

 void init()
 {
     topA=0;
     topB=0;
     memset(headA,-1,sizeof(headA));
     memset(headB,-1,sizeof(headB));
 }

 unsigned int BKDRhash(char* str)
 {
    unsigned int seed=131;
    unsigned int hash1=0;
    while(*str)
    {
        hash1=hash1*seed + *str++;
    }
    return (hash1 & 0x7fffffff) % mod;
 }

 void inserthash(char * key,char * ans)
 {
     unsigned int h;

     h=BKDRhash(key);
     strcpy(nodeA[topA].key,key);
     strcpy(nodeA[topA].ans,ans);
     nodeA[topA].nex=headA[h];
     headA[h]=topA;
     topA++;

     h=BKDRhash(ans);
     strcpy(nodeB[topB].key,key);
     strcpy(nodeB[topB].ans,ans);
     nodeB[topB].nex=headB[h];
     headB[h]=topB;
     topB++;
 }

 char * searchhash(char * key ,int on)
 {
       unsigned int h=BKDRhash(key);
       if(on==1)
       {
            for(int i=headA[h];i!=-1;i=nodeA[i].nex)
            {
                if(strcmp(nodeA[i].key,key)== 0)
                {
                    return nodeA[i].ans;
                }
            }
       }
       else
       {
           for(int i=headB[h];i!=-1;i=nodeB[i].nex)
           {
               if(strcmp(nodeB[i].ans,key)==0)
               {
                   return nodeB[i].key;
               }
           }
       }

       return "what?";
 }
 string str;
 char que[25];
 char ans[85];
 char query[120];
int main()
{
#ifndef ONLINE_JUDGE
    freopen("coco.txt","r",stdin);
    freopen("lala.txt","w",stdout);
#endif
    init();
    while(getline(cin,str))
    {
        if(str[0] == '@' )break;
        int len=0;
        int i;
        for(i=1;str[i]!=']';i++)
        {
            que[len++]=str[i];
        }
        que[len]='\0';

        i+=2;

        len=0;
        for(;str[i]!='\0';i++)
        {
            ans[len++]=str[i];
        }
        ans[len]='\0';

        inserthash(que,ans);
    }
    int n;

    scanf("%d",&n);
    getchar();
    while(n--)
    {
        getline(cin,str);
        if(str[0]=='[')
        {
            int len=0;
            for(int i=1;str[i]!=']';i++)
            {
                query[len++]=str[i];
            }
            query[len]='\0';

            printf("%s\n",searchhash(query,1));
        }
        else
        {
            int len=0;
            for(int i=0;str[i]!='\0';i++)
            {
                query[len++]=str[i];
            }
            query[len]='\0';

            printf("%s\n",searchhash(query,-1));

        }
    }

    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值