D - 魔咒词典 HDU - 1880(unordered_map \ 字符串hash)

分析

  • 题意
  1. 给我们 魔咒 和 对应的内容,给我 魔咒 让我们输出 对应的内容字符串,给我们 内容字符串 让我们输出 魔咒字符串,如果查找不到输出 输出“What!”
  • 思路
  1. 代码一:每行的 魔咒 和 对应的内容 当作 map 的 key 和 val ,之后在反过来
  2. 代码二
    1. 假如给我 魔咒 让我们 查找魔咒对应的内容,我们先把所给的文本总的 内容按输入顺序存储到 一个数组spell[][]中,我们 通过hash把所有 魔咒字符串 转化为 hash数值,
    2. 我们把这个每个 魔咒的hash数值和其下表 存储到,一个结构体中数组中,通过对这个 结构体数组 按从 hans数值 从小到大排序,我们在通过 lower_bound() 去查找 某个魔咒hash值是否存在,如果存在我们就可 获得 这个魔咒hash值的在结构题数组中的数组 下标,有了这个下标,就可以得到 这个魔咒在输入的时候的下标idx,通过idx的到 spell中存储的 魔咒对应的内容

代码一(unordered_map)

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <algorithm>
#include <string>
#include <queue>
#include <map>
#include <set>
#include <bitset>
#include <vector>
#include <stack>
#include <unordered_map>
#include <sstream>
void fre() { system("clear"), freopen("A.txt", "r", stdin); freopen("Ans.txt","w",stdout); }
void Fre() { system("clear"), freopen("A.txt", "r", stdin);}
#define ios ios::sync_with_stdio(false)
#define Pi acos(-1)
#define pb push_back
#define fi first
#define se second
#define ll long long
#define ull unsigned long long
#define db double
#define Pir pair<int, int>
#define m_p make_pair
#define INF 0x3f3f3f3f
#define esp 1e-7
#define mod (ll)(1e9 + 7)
#define for_(i, s, e) for(int i = (ll)(s); i <= (ll)(e); i ++)
#define rep_(i, e, s) for(int i = (ll)(e); i >= (ll)(s); i --)
#define sc scanf
#define pr printf
#define sd(a) scanf("%d", &a)
#define ss(a) scanf("%s", a)
using namespace std;

unordered_map<string, string> mp;
string s, a, b;

int main()
{
    /* fre(); */
    ios;
    while(getline(cin, s) && s[0] != '@')
    {
        int i = 0;
        while(s[i] != ']') i ++;
        a = s.substr(0, i + 1);
        b = s.substr(i + 2, s.size() - i - 2);
        mp[a] = b;
        mp[b] = a;
    }

    int n;

    cin >> n;
    /* getchar();      //这里的 getchar 不要忘记否则会被 getline() 吸收 */
        getline(cin, s);
    while(n --)
    {
        getline(cin, s);
        if(mp[s].size() == 0)
            cout << "what?" << endl;
        else
        {
            if(s[0] == '[' && s[s.size() - 1] == ']')
                cout << mp[s] << endl;
            else
            {
                s = mp[s];
                cout << s.substr(1, s.size() - 2) << endl;
            }
        }
    }

    return 0;
}

代码(Hash)

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <algorithm>
#include <string>
#include <queue>
#include <map>
#include <set>
#include <bitset>
#include <vector>
#include <stack>
#include <unordered_map>
#include <sstream>
void fre() { system("clear"), freopen("A.txt", "r", stdin); freopen("Ans.txt","w",stdout); }
void Fre() { system("clear"), freopen("A.txt", "r", stdin);}
#define ios ios::sync_with_stdio(false)
#define Pi acos(-1)
#define pb push_back
#define fi first
#define se second
#define ll long long
#define ull unsigned long long
#define db double
#define Pir pair<int, int>
#define m_p make_pair
#define INF 0x3f3f3f3f
#define esp 1e-7
#define mod (ll)(1e9 + 7)
#define for_(i, s, e) for(int i = (ll)(s); i <= (ll)(e); i ++)
#define rep_(i, e, s) for(int i = (ll)(e); i >= (ll)(s); i --)
#define sc scanf
#define pr printf
#define sd(a) scanf("%d", &a)
#define ss(a) scanf("%s", a)
using namespace std;

const int mxn = 100005;

char spell[mxn][25];
char magic[mxn][85];
char s[105];
int nm = 0;

struct Node
{
    int hs;         //对应下标序列的哈希值
    int idx;
} key[mxn], val[mxn];

bool cmp(Node a, Node b)
{
    return a.hs < b.hs;
}

int Hash(char s[])
{
    unsigned int seed = 131;
    unsigned int hash = 0;
    while(*s)
    {
        hash = hash * seed + (*s ++);
    }
    return hash % 0x7fffffff;
}

void init()
{
    for_(i, 0, nm - 1)
    {
        key[i] = (Node){ Hash(spell[i]), i };
        val[i] = (Node){ Hash(magic[i]), i };        
    }
    sort(key, key + nm, cmp);
    sort(val, val + nm, cmp);
}

int main()
{
    /* fre(); */
    while(ss(s) && s[0] != '@')
    {
        strcpy(spell[nm], s);
        getchar();
        gets(s);
        strcpy(magic[nm ++], s);
    }

    init();
    int n; sd(n); getchar();

    while(n --)
    {
        gets(s);
        Node tmp = (Node){ Hash(s), 0 };
        if(s[0] == '[')
        {
            int p = lower_bound(key, key + nm, tmp, cmp) - key;
            if(tmp.hs != key[p].hs)         //如果没有找到 
                pr("what?\n");
            else
                pr("%s\n", magic[key[p].idx]);
        }
        else
        {
            int p = lower_bound(val, val + nm, tmp, cmp) - val;
            if(tmp.hs != val[p].hs)         //如果没有找到 
                pr("what?\n");
            else
            {
                int n = strlen(spell[val[p].idx]);
                spell[val[p].idx][n - 1] = '\0';
                pr("%s\n", spell[val[p].idx] + 1);
            }
        }

    }

    return 0;
}

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值