尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
Java实现斗地主顺子牌型判断算法
1. 题目背景与需求解析这道来自华为OD机考双机位C卷的编程题要求我们实现斗地主游戏中的顺子牌型判断逻辑。顺子是斗地主中最基础的牌型之一也是实战中出现频率最高的组合牌型。题目限定使用Java语言实现考察点集中在集合操作、边界条件处理和算法效率上。在实际开发中类似的需求常出现在棋牌游戏服务器端逻辑验证模块。我曾参与过某地方棋牌平台的开发其中牌型验证的代码约占总逻辑的30%而顺子判断又是其中调用最频繁的部分。一个高效的顺子判断算法能显著降低服务器CPU负载。2. 顺子规则的技术定义2.1 基本规则说明顺子需要满足三个核心条件牌数要求至少5张最多12张3-A的连续序列连续性牌面数字必须连续递增花色无关不考虑花色差异例如合法顺子[3,4,5,6,7]、[10,J,Q,K,A]非法顺子[3,4,5,7]不连续、[2,3,4,5,6]含22.2 牌面数值映射需要建立牌面字符到可比数值的映射表MapString, Integer cardValue new HashMap(); cardValue.put(3, 3); cardValue.put(4, 4); ... cardValue.put(10, 10); cardValue.put(J, 11); cardValue.put(Q, 12); cardValue.put(K, 13); cardValue.put(A, 14); // 注意A作为最大值特别注意2不参与顺子组合这在业务规则上需要特殊处理3. 核心算法实现3.1 预处理阶段public boolean isStraight(ListString cards) { // 过滤无效输入 if (cards null || cards.size() 5 || cards.size() 12) { return false; } // 转换牌面数值并排序 ListInteger values new ArrayList(); for (String card : cards) { if (card.equals(2)) return false; // 2不能出现在顺子中 Integer val cardValue.get(card); if (val null) return false; // 非法牌面 values.add(val); } Collections.sort(values); }3.2 连续性校验// 检查是否连续 for (int i 1; i values.size(); i) { if (values.get(i) - values.get(i-1) ! 1) { return false; } } return true;3.3 性能优化方案对于高频调用的场景可以采用以下优化使用int[]替代List 减少装箱开销提前终止检查发现不连续立即返回使用位运算进行快速验证适用于固定长度顺子4. 边界条件处理4.1 特殊牌型处理特殊情况处理方式包含大小王直接返回false重复牌需要去重后再判断空输入返回false单张A可参与[A,2,3,4,5]这种特殊顺子本题不考虑4.2 代码健壮性增强// 添加重复牌检测 SetInteger uniqueValues new HashSet(values); if (uniqueValues.size() ! values.size()) { return false; }5. 测试用例设计5.1 常规测试用例Test public void testNormalCases() { assertTrue(isStraight(Arrays.asList(3,4,5,6,7))); assertFalse(isStraight(Arrays.asList(3,4,5,6))); // 不足5张 assertFalse(isStraight(Arrays.asList(3,4,5,7,8))); // 不连续 }5.2 边界测试用例Test public void testEdgeCases() { // 最大长度顺子 assertTrue(isStraight(Arrays.asList(3,4,5,6,7,8,9,10,J,Q,K,A))); // 包含2 assertFalse(isStraight(Arrays.asList(A,2,3,4,5))); // 重复牌 assertFalse(isStraight(Arrays.asList(3,4,5,6,6))); }6. 工程实践建议6.1 对象化设计在实际项目中建议采用面向对象设计public class Card { private int value; private String suit; // 构造方法、getter等 } public class CardUtils { private static final MapString, Integer VALUE_MAP /* 初始化映射 */; public static boolean isStraight(ListCard cards) { // 实现逻辑 } }6.2 多规则扩展考虑未来可能扩展的规则双顺如556677飞机三张连续的牌特殊顺子如A-5可以在初始设计时预留扩展点public interface CardRule { boolean check(ListCard cards); } public class StraightRule implements CardRule { Override public boolean check(ListCard cards) { // 实现逻辑 } }7. 算法复杂度分析7.1 时间复杂度排序阶段O(nlogn)使用Java默认的TimSort遍历检查O(n)总体复杂度O(nlogn)7.2 空间复杂度存储转换后的数值O(n)去重检查O(n)总体空间O(n)对于斗地主场景n最大为123-A的顺子实际性能差异不大。但在德州扑克等需要判断7张牌的游戏中算法选择会更关键。8. 实际开发中的踩坑记录牌面大小写问题客户端可能传j而非J建议统一转为大写cardValue.get(card.toUpperCase());并发安全问题如果cardValue映射是共享的需要private static final MapString, Integer CARD_VALUE; static { MapString, Integer map new HashMap(); // 初始化 CARD_VALUE Collections.unmodifiableMap(map); }性能热点在百万级对局统计中发现该函数占用了15%的CPU时间。最终通过以下优化缓存常见顺子模式使用快速失败策略改为原生数组操作9. 相似题目拓展掌握顺子判断后可以解决以下变种问题连对判断如334455飞机带翅膀三顺德州扑克中的顺子判断需考虑A作为低位的情况例如德州扑克的顺子判断// A可以作为1使用 if (values.contains(14)) { values.add(1); // 添加A作为1的可能性 Collections.sort(values); // 重新检查 }10. 完整实现参考import java.util.*; public class PokerUtil { private static final MapString, Integer CARD_VALUE; static { MapString, Integer map new HashMap(); for (int i 3; i 10; i) { map.put(String.valueOf(i), i); } map.put(J, 11); map.put(Q, 12); map.put(K, 13); map.put(A, 14); CARD_VALUE Collections.unmodifiableMap(map); } public static boolean isStraight(ListString cards) { // 基础检查 if (cards null || cards.size() 5 || cards.size() 12) { return false; } // 转换并过滤 ListInteger values new ArrayList(); for (String card : cards) { Integer val CARD_VALUE.get(card.toUpperCase()); if (val null || val 2) return false; // 包含2或无效牌 values.add(val); } // 去重检查 SetInteger unique new HashSet(values); if (unique.size() ! values.size()) return false; // 排序检查 Collections.sort(values); for (int i 1; i values.size(); i) { if (values.get(i) - values.get(i-1) ! 1) { return false; } } return true; } }在真实项目开发中这类基础算法要特别注意三点一是业务规则的准确实现二是异常输入的壮处理三是高频调用时的性能优化。建议在代码审查时重点检查这三个方面。
RELATED

相关推荐

Linux内网离线安装MySQL:选型、介质准备与避坑指南

Linux内网离线安装MySQL:选型、介质准备与避坑指南

内网装 MySQL 这件事,第一次碰到基本都会卡在同一个地方:习惯性敲下yum install mysql-server,回车,屏幕上甩回来一句 "No package mysql-server available"。外网不通,内网的 yum 源里又没有 MySQL 的包&am…

📅 2026/9/18 10:55:00
LLVM实战指南:从仓库构建到自定义Pass开发

LLVM实战指南:从仓库构建到自定义Pass开发

很多人第一次听说 LLVM,第一反应是"哦,一个编译器"。等真正打开 llvm-project 这个仓库,看到那一长串子项目目录,才发现事情远没有那么简单——Clang 只是冰山一角,里面有优化器、链接器、标准库、调试器组件…

📅 2026/9/18 10:55:00
Oracle varchar2长度限制全解析:字节与字符的较量

Oracle varchar2长度限制全解析:字节与字符的较量

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📅 2026/9/18 10:55:00
MORE NEWS

更多资讯

📰

什么是折腾一个优化:渐进式工程优化方法论

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📰

Linux操作系统如何设置墨西哥时区

sudo ln -sf /usr/share/zoneinfo/Mexico/General /usr/share/zoneinfo/GMT-06:00/usr/share/zoneinfo/Mexico/General为真实存在的linux文件:[roottest]# ll /usr/share/zoneinfo/Mexico/General -rw-r--r-- 2 root root 1222 Feb 14 2024 /usr/share/zoneinfo/Me…

📰

【ComfyUI】Z-Image + ControlNet 姿态搭配双LoRA图生图

今天给大家演示一个基于 Z-Image-Turbo + Qwen Image + ControlNet 的 ComfyUI 综合工作流。该工作流以「参考图像驱动 + 自动图像理解 + 二次采样精修」为核心思路,通过对输入图片进行结构预处理、语义描述生成与模型联合控制,实现高一致性、高还原度的人像写真生成。 整体流…

📰

【ComfyUI】Z-Image 基础反推洗图

今天给大家演示一个 基于图像理解 + 文生图生成 + 高清放大的 ComfyUI 综合工作流。 该工作流以参考图像为输入,通过自动图像描述生成高质量提示词,再结合高速文生图模型完成画面重绘,最后使用 SeedVR2 进行高分辨率放大输出。 整体流程强调“从图到文,再从文回到高质量图像…

📰

【ComfyUI】Flux + Kontext 清除图片马赛克

今天给大家演示一个基于 Flux Kontext 的 ComfyUI 图像修复与重绘工作流。这个流程以「被遮挡 / 被打码图像的理解与还原」为核心目标,通过引入参考图像、上下文条件约束以及 Flux 系列模型的引导能力,实现对马赛克、模糊、遮挡区域的智能重建。 结合效果展示图可以看到,工作…

📰

【ComfyUI】Qwen VL 图像反推描述词

今天带大家演示一套基于 Qwen2-VL 的 ComfyUI 图像反推描述词工作流。整个流程围绕“上传图像、调用大模型解析、输出精细文本描述”展开,让读者能直观看到如何把图片内容转成可直接使用的描述词。工作流结构简单但高效,核心由图像加载、视觉语言模型推理、文本展示三部分组成…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬