PAT 1100 校庆 (25 分)

1100 校庆 (25 分)

原题请点击我

哈希表的简单应用

数据的范围在1e5,暴力遍历肯定会超时,所以需要对使用哈希表或者二分查找来降低时间复杂度,哈希表更暴力更直接,所以这里介绍哈希表的做法

  • 使用一个哈希表存放所有校友的身份证号码,并记录下来校友中最年迈的那个人
  • 输入来宾的身份证号,并在哈希表中查找,如果存在这个人,那么参加校庆的校友数量就 + 1。在查找的同时并维护来宾中最年迈的那个人,并且检查校友中最年迈的那个人是否来了,如果来了的话,使用一个标志位记录下来。
  • 如果那个标志位有值的话,则输出最年迈的校友的身份证号,否则,输出最年迈来宾的身份证号。

c++代码:

#include<bits/stdc++.h>
using namespace std;
int main(){
    int n;
    cin >> n;
    unordered_map<string, int> m;
    int year = 0, month = 0 , day = 0;
    int yearN = INT_MAX, monthN = INT_MAX, dayN = INT_MAX;
    int k = -1;
    vector<string> t(n);
    for (int i = 0; i < n; i++){
        cin >> t[i];
        pair<string, int> p(t[i], i);
        m.insert(p);
        
        for (int j = 6; j < 10; j++){
            year = year * 10 + (t[i][j] - '0');            
        }
        for (int j = 10; j < 12; j++){
            month = month * 10 + (t[i][j] - '0');
        }
        for (int j = 12; j < 14; j++) {
            day = day * 10 + (t[i][j] - '0');
        }
        if (year < yearN) {
            yearN = year, monthN = month, dayN = day, k = i;
        } else if (year == yearN) {
            if (month < monthN) {
                monthN = month, dayN = day, k = i;
            } else if (month == monthN) {
                if (day < dayN) {
                    dayN = day, k = i;
                }
            }
        }
        year = 0, month = 0, day = 0;
    }
    int mm;
    cin >> mm;
    int re = 0;
    vector<string> tt(mm);
    year = 0, month = 0, day = 0;
    int yearNN = INT_MAX, monthNN = INT_MAX, dayNN = INT_MAX;
    int k2 = -1;
    bool flag = false;
    for (int i = 0; i < mm; i++){
        cin >> tt[i];
        if (tt[i] == t[k]){
            flag = true;
        }
        if (m.count(tt[i])) {
            re++;
        }
        for (int j = 6; j < 10; j++){
            year = year * 10 + (tt[i][j] - '0');            
        }
        for (int j = 10; j < 12; j++){
            month = month * 10 + (tt[i][j] - '0');
        }
        for (int j = 12; j < 14; j++) {
            day = day * 10 + (tt[i][j] - '0');
        }
        if (year < yearNN) {
            yearNN = year, monthNN = month, dayNN = day, k2 = i;
        } else if (year == yearNN) {
            if (month < monthNN) {
                monthNN = month, dayNN = day, k2 = i;
            } else if (month == monthNN) {
                if (day < dayNN) {
                    dayNN = day, k2 = i;
                }
            }
        }
        year = 0, month = 0, day = 0;
    }
    cout << re << endl;
    if (flag) {
        cout << t[k];
    } else {
        cout << tt[k2];
    }
}

  • 值得注意的是,在哈希表中使用string作为键的时候,在哈希表中存储的并不是这个string的值,而是这个string的地址
  • 在内存模型中,string属于字符串常量,也就是说两个string是相等的,那么他们的地址也是相同的,这和int不一样,两个int相同,地址可能是不同的,但是两个string相同,地址就是相同的。
  • 当然了,如果你把string申请在堆中,两个string的值相同的,地址也有可能是不同的,这里我们并没有将其申请在堆中,而是申请在常量区,所以在哈希表中的映射才会是正确的。
  • 而如果将string在堆申请内存,哈希表就会出错,因为可能两个string的值分明是相同的,但是在哈希表中查找的时候却找不到,原因是将string申请在了堆中。

  • 觉得我写的还不错的,可以点个赞哦
  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值