牛客网4874题:C++实现扑克牌比大小的完整解析

一、题目解读
本题要求实现一个扑克牌比较系统,模拟"炸金花"游戏的牌型判定规则。核心难点在于:
多维度牌型识别(6种牌型)
特殊组合处理(王炸、炸弹)
权重系统设计(3最小,JOKER最大)
异常输入处理(ERROR)
二、解题思路分析
采用"分类处理+优先级队列"思想:
三、解题步骤详解
四、完整代码实现
#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;
}原创内容 转载请注明出处
