自动化顺子数字序列验证:多长度字符场景代码优化需求
顺子验证问题优化方案
核心思路
针对多字符手牌的顺子验证、存在性判断及连续字符统计需求,调整核心逻辑如下:
- 统一字符到数值的映射,特殊处理A的双值(1和14)以兼容两种顺子场景(A-2-3-4-5、10-J-Q-K-A)
- 对牌值去重后排序,避免重复牌干扰连续序列判断
- 用滑动窗口法遍历排序后的数值,统计最长连续递增序列长度,同时判断是否存在长度≥5的顺子
优化后的VBA代码
' 自定义类型:存储顺子检查结果 Type StraightCheckResult HasStraight As Boolean ' 是否存在5张及以上的顺子 MaxConsecutiveCount As Integer ' 最长连续字符数量 End Type ' 主函数:检查手牌的顺子情况 Function CheckStraight(sHand As String) As StraightCheckResult Dim cardValues As Collection Dim uniqueValues As Collection Dim i As Integer, char As String, val As Integer Dim sortedVals() As Integer Dim maxLen As Integer, currentLen As Integer Dim result As StraightCheckResult Set cardValues = New Collection Set uniqueValues = New Collection ' 字符到数值的映射规则,A同时对应1和14 Const cardRankMap As String = "A:1,2:2,3:3,4:4,5:5,6:6,7:7,8:8,9:9,T:10,J:11,Q:12,K:13" Dim mapParts() As String, part() As String mapParts = Split(cardRankMap, ",") ' 转换手牌字符为数值 For i = 1 To Len(sHand) char = Mid(sHand, i, 1) For Each mapPart In mapParts part = Split(mapPart, ":") If UCase(part(0)) = UCase(char) Then val = CInt(part(1)) cardValues.Add val ' 为A额外添加14,适配A-J-Q-K-A的顺子 If char = "A" Then cardValues.Add 14 Exit For End If Next mapPart Next i ' 去重:提取唯一数值 On Error Resume Next For Each val In cardValues uniqueValues.Add val, Key:=CStr(val) Next val On Error GoTo 0 ' 转换为数组并排序 ReDim sortedVals(1 To uniqueValues.Count) For i = 1 To uniqueValues.Count sortedVals(i) = uniqueValues(i) Next i BubbleSort sortedVals ' 统计最长连续序列 maxLen = 1 currentLen = 1 For i = 2 To UBound(sortedVals) If sortedVals(i) = sortedVals(i - 1) + 1 Then currentLen = currentLen + 1 maxLen = IIf(currentLen > maxLen, currentLen, maxLen) Else currentLen = 1 End If Next i ' 组装结果 result.HasStraight = (maxLen >= 5) result.MaxConsecutiveCount = maxLen CheckStraight = result End Function ' 辅助排序函数:冒泡排序(适合小数据量场景) Sub BubbleSort(arr() As Integer) Dim i As Integer, j As Integer, temp As Integer For i = LBound(arr) To UBound(arr) - 1 For j = i + 1 To UBound(arr) If arr(i) > arr(j) Then temp = arr(i) arr(i) = arr(j) arr(j) = temp End If Next j Next i End Sub ' Excel单元格直接调用函数:判断是否存在顺子 Function CheckStraightHas(sHand As String) As Boolean CheckStraightHas = CheckStraight(sHand).HasStraight End Function ' Excel单元格直接调用函数:获取最长连续字符数 Function CheckStraightCount(sHand As String) As Integer CheckStraightCount = CheckStraight(sHand).MaxConsecutiveCount End Function
关键说明
- 双值处理A:将A同时映射为1和14,确保能识别两种顺子场景,覆盖所有合法顺子组合
- 去重逻辑:重复的牌值不影响顺子判断,去重后减少遍历次数,提升处理效率
- 滑动窗口统计:仅需遍历一次排序后的数组即可得到最长连续序列,时间复杂度主要由排序决定,适合手牌字符数不多的场景
- 易用性:封装了两个Excel单元格可直接调用的函数,无需复杂操作即可获取结果
测试验证
| 手牌字符串 | 是否有顺子 | 最长连续数 |
|---|---|---|
| "23465148" | TRUE | 5 |
| "237TK" | FALSE | 3 |
| "A2345" | TRUE | 5 |
| "JQKA2" | TRUE | 5 |
| "123" | FALSE | 3 |
内容的提问来源于stack exchange,提问作者Raphaël Ambit
相关产品推荐
相关产品推荐

