当前位置:首页 > 牛客 > 牛客网4874题:用哈希表解决扑克牌比大小

牛客网4874题:用哈希表解决扑克牌比大小

2个月前 (07-29)

牛客网4874题:用哈希表解决扑克牌比大小 牛客题解 哈希表 C++ 第1张

一、题目解读

牛客网4874题要求实现一个扑克牌比较算法,输入两手牌(如"3-4-5"与"JOKER-JOKER"),判断其胜负关系。题目涉及多种牌型优先级:对王(大小王对子)>炸弹(四张相同牌)>顺子(五张连续牌)>三个、对子、个子,且需处理错误输入格式。核心挑战在于高效判断牌型并比较权重,确保逻辑严谨性与代码性能。

二、解题思路

1. 数据结构优化:使用unordered_map将牌面值(如"3"、"J")映射为数值权重(1-15),避免字符串比较耗时,加速牌型判断。

2. 枚举牌型:定义CardType枚举简化牌型分类,便于后续逻辑分支与权重赋值。

3. 分情况讨论:按牌数量(2/3/4/5)逐级判断对王、炸弹、顺子等特殊牌型,减少冗余计算。

4. 权重比较:牌型优先级通过枚举值隐式排序(如JOKER_PAIR=15最高),相同牌型则比较首牌权重。

5. 错误处理:输入格式错误时返回"ERROR",增强程序鲁棒性。

三、解题步骤

1. 输入解析:通过find('-')定位分隔符,分割两手牌字符串为子串数组

2. 牌型与权重获取:调用getCardType()函数,根据牌数量及连续性判断牌型,返回<牌型枚举, 权重>。

3. 比较逻辑:若牌型不同,直接比较枚举值;若相同,则比较权重(如炸弹比较四张牌的数值)。

4. 输出结果:根据比较结果返回胜负标识(如"胜"、"负"、"平")。

四、代码和注释

#include <iostream>
#include <vector>
#include <string>
#include <unordered_map>
#include <sstream>
#include <algorithm>

using namespace std;

// 扑克牌权重映射表(优化比较效率)
const unordered_map<string, int> CARD_RANK = {
    {"3", 1}, {"4", 2}, {"5", 3}, {"6", 4},
    {"7", 5}, {"8", 6}, {"9", 7}, {"10", 8},
    {"J", 9}, {"Q", 10}, {"K", 11}, {"A", 12},
    {"2", 13}, {"joker", 14}, {"JOKER", 15}
};

// 牌型枚举
enum CardType {
    SINGLE = 1,    // 单个
    PAIR,          // 对子
    TRIPLE,        // 三个
    BOMB,          // 炸弹
    STRAIGHT,      // 顺子
    JOKER_PAIR     // 对王
};

// 核心函数:根据牌列表返回牌型与权重
pair<CardType, int> getCardType(const vector<string>& cards) {
    int size = cards.size();
    // 对王判断(最高优先级)
    if (size == 2 && cards[0] == "joker" && cards[1] == "JOKER") {
        return {JOKER_PAIR, 15};
    }
    // 炸弹判断(四张相同)
    if (size == 4 && all_of(cards.begin(), cards.end(), 
        [&](const string& s){return s == cards[0];})) {
        return {BOMB, CARD_RANK.at(cards[0])};
    }
    // 顺子判断(五张连续)
    if (size == 5) {
        bool is_straight = true;
        for (int i = 0; i < 4; ++i) {
            if (CARD_RANK.at(cards[i+1]) - CARD_RANK.at(cards[i])!= 1) {
                is_straight = false;
                break;
            }
        }
        if (is_straight) {
            return {STRAIGHT, CARD_RANK.at(cards[0])};
        }
    }
    // 三个、对子、个子判断(逐级递减)
    if (size == 3 && cards[0] == cards[1] && cards[1] == cards[2]) {
        return {TRIPLE, CARD_RANK.at(cards[0])};
    }
    if (size == 2 && cards[0] == cards[1]) {
        return {PAIR, CARD_RANK.at(cards[0])};
    }
    return {SINGLE, CARD_RANK.at(cards[0])};
}

// 比较两手牌
string compareCards(const string& input) {
    size_t pos = input.find('-');
    if (pos == string::npos) return "ERROR";
    
    vector<string> cards1, cards2;
    istringstream iss(input.substr(0, pos));
    string card;
    while (iss >> card) cards1.push_back(card);
    
    iss = istringstream(input.substr(pos + 1));
    while (iss >> card) cards2.push_back(card);
    
    auto [type1, rank1] = getCardType(cards1);
    auto [type2, rank2] = getCardType(cards2);
    
    // 处理特殊牌型
    if (type1 == JOKER_PAIR) return input.substr(0, pos);
    if (type2 == JOKER_PAIR) return input.substr(pos + 1);
    if (type1 == BOMB && type2 != BOMB) return input.substr(0, pos);
    if (type2 == BOMB && type1 != BOMB) return input.substr(pos + 1);
    
    // 同类型比较
    if (type1 == type2) {
        return (rank1 > rank2) ? input.substr(0, pos) : input.substr(pos + 1);
    }
    
    return "ERROR";
}

int main() {
    string input;
    getline(cin, input);
    cout << compareCards(input) << endl;
    return 0;
}

五、总结

本文代码通过以下策略高效解决扑克牌比较问题:

● 利用哈希表与枚举类型实现O(1)牌值映射与牌型分类;

分治思想简化逻辑复杂度,优先处理高优先级牌型;

● 结合all_of、find等算法库函数提升代码简洁性;

● 严谨的错误处理增强实用性。

该算法为棋牌类游戏开发中的牌型判定提供了可复用的模板,亦展示了数据结构选择与逻辑分层对算法性能的关键影响。


原创内容 转载请注明出处

分享给朋友:

相关文章

【深度优先搜索实战】力扣547题:省份数量问题的图论解法

【深度优先搜索实战】力扣547题:省份数量问题的图论解法

题目解读‌我们面对的是一个典型的图论问题:给定一个城市的连接矩阵,需要计算其中相互连通的城市群(省份)数量。这个问题可以抽象为无向图中的连通分量计算,每个城市代表图中的一个节点,城市之间的连接关系代表...

力扣145:递归之美 轻松掌握二叉树后序遍历

力扣145:递归之美 轻松掌握二叉树后序遍历

题目解读二叉树的后序遍历是一种基础且重要的树遍历方式,其遍历顺序为:先递归地后序遍历左子树,然后递归地后序遍历右子树,最后访问根节点。这种遍历方式特别适合需要先处理子节点再处理父节点的场景,如内存释放...

牛客14496题解:括号最大深度问题(栈思想与代码优化)

牛客14496题解:括号最大深度问题(栈思想与代码优化)

一、题目解读牛客14496题要求计算给定括号字符串中的最大深度。例如,对于字符串 "(()())",最大深度为2。题目考察对括号嵌套结构的理解,以及如何通过编程找到最深嵌套层次。二...

洛谷P2190题解:铁路售票系统车厢计算(差分数组+前缀和优化)

洛谷P2190题解:铁路售票系统车厢计算(差分数组+前缀和优化)

一、题目解读洛谷P2190题要求解决铁路售票系统中的车厢数量计算问题。题目给定n个车站和m条订票申请,每条申请包含区间[x,y)及乘客数z。需要计算在不超载的情况下(每节车厢最多36人),满足所有乘客...

洛谷2652题解析:同花顺排序问题的动态规划与滑动窗口优化

洛谷2652题解析:同花顺排序问题的动态规划与滑动窗口优化

一、题目解读洛谷2652题要求对一组扑克牌进行排序,目标是找到最少需要调整的次数,使得所有牌形成同花顺。题目中,扑克牌由花色和数字组成,需先按花色排序,再在同花色内按数字排序。核心难点在于如何处理花色...

牛客4432题解题全解析:矩阵快速幂优化楼梯攀登问题(附C++代码)

牛客4432题解题全解析:矩阵快速幂优化楼梯攀登问题(附C++代码)

一、题目解读牛客4432题要求计算在n阶楼梯中,每次可爬1阶或2阶,共有多少种不同的攀登方式。该问题属于经典的动态规划类题目,需通过数学递推或矩阵乘法优化算法以应对较大数据规模。题目核心在于寻找高效计...

发表评论

访客

看不清,换一张

◎欢迎参与讨论,请在这里发表您的看法和观点。