如何在Visual Basic.NET的ListBox中按指定行数搜索单码、对子与三连号?
VB.NET 彩票分析程序:ListBox号码筛选实现(单码、对子、三连号)
核心思路拆解
先把ListBox里的原始开奖数据拆成可处理的结构化格式,再结合NumericUpDown指定的行范围,用循环遍历目标数据,分别实现三类统计/检测逻辑。
1. 数据预处理:解析ListBox中的开奖数据
ListBox每一项格式为期号 - 号码1 号码2 ... 号码6,第一步要将其拆分为期号和整数类型的号码数组,并对号码数组排序(这是后续对子、三连号检测的关键)。
示例解析代码:
' 解析单条ListBox项 Private Function ParseDrawData(item As String) As (period As String, numbers As List(Of Integer)) ' 按" - "分割期号与号码部分 Dim parts = item.Split({" - "}, StringSplitOptions.RemoveEmptyEntries) If parts.Length <> 2 Then Return (String.Empty, New List(Of Integer)) ' 分割号码字符串并转成整数,最后排序 Dim numberStrs = parts(1).Split({" "}, StringSplitOptions.RemoveEmptyEntries) Dim numbers = New List(Of Integer)() For Each numStr In numberStrs If Integer.TryParse(numStr, Dim num) Then numbers.Add(num) End If Next numbers.Sort() Return (parts(0), numbers) End Function
2. 范围确定:获取NumericUpDown指定的目标行
假设你用两个NumericUpDown控件:nudStartRow(起始行,从1计数)和nudEndRow(结束行),需转换为ListBox的索引(ListBox索引从0开始),同时做边界校验防止越界:
Dim startIndex = CInt(nudStartRow.Value) - 1 Dim endIndex = CInt(nudEndRow.Value) - 1 startIndex = Math.Max(0, startIndex) endIndex = Math.Min(ListBox1.Items.Count - 1, endIndex)
3. 单码统计算法
用Dictionary(Of Integer, Integer)记录每个号码在范围内的出现次数,遍历目标行的所有号码逐个累加计数:
Dim singleCodeStats As New Dictionary(Of Integer, Integer)() For i = startIndex To endIndex Dim drawData = ParseDrawData(ListBox1.Items(i).ToString()) For Each num In drawData.numbers If singleCodeStats.ContainsKey(num) Then singleCodeStats(num) += 1 Else singleCodeStats(num) = 1 End If Next Next ' 示例:将结果输出到TextBox TextBox1.Clear() TextBox1.AppendText("=== 单码出现统计 ===" & vbCrLf) For Each kvp In singleCodeStats.OrderBy(Function(x) x.Key) TextBox1.AppendText($"号码{kvp.Key.ToString("D2")}: {kvp.Value}次" & vbCrLf) Next
4. 对子检测算法
这里的对子指同一开奖期内重复出现的号码,利用排序后的数组,只需检查相邻元素是否相等,同时避免重复记录同一对子(比如三个相同号码只记一次):
Dim pairResults As New List(Of String)() For i = startIndex To endIndex Dim drawData = ParseDrawData(ListBox1.Items(i).ToString()) Dim foundPairs As New List(Of Integer)() For j = 0 To drawData.numbers.Count - 2 If drawData.numbers(j) = drawData.numbers(j + 1) Then If Not foundPairs.Contains(drawData.numbers(j)) Then foundPairs.Add(drawData.numbers(j)) End If End If Next If foundPairs.Count > 0 Then pairResults.Add($"期号{drawData.period}: 对子号码{String.Join(", ", foundPairs.Select(Function(n) n.ToString("D2")))}") End If Next ' 输出结果 TextBox1.AppendText(vbCrLf & "=== 对子检测结果 ===" & vbCrLf) If pairResults.Count = 0 Then TextBox1.AppendText("范围内无对子" & vbCrLf) Else For Each result In pairResults TextBox1.AppendText(result & vbCrLf) Next End If
5. 三连号检测算法
三连号指同一开奖期内连续递增1的三个号码(比如18、19、20),同样基于排序后的数组,检查连续三个元素是否满足递加1的条件:
Dim tripleResults As New List(Of String)() For i = startIndex To endIndex Dim drawData = ParseDrawData(ListBox1.Items(i).ToString()) Dim foundTriples As New List(Of String)() For j = 0 To drawData.numbers.Count - 3 If drawData.numbers(j + 1) = drawData.numbers(j) + 1 AndAlso drawData.numbers(j + 2) = drawData.numbers(j + 1) + 1 Then Dim tripleStr = $"{drawData.numbers(j).ToString("D2")}-{drawData.numbers(j+1).ToString("D2")}-{drawData.numbers(j+2).ToString("D2")}" foundTriples.Add(tripleStr) End If Next If foundTriples.Count > 0 Then tripleResults.Add($"期号{drawData.period}: 三连号{String.Join(", ", foundTriples)}") End If Next ' 输出结果 TextBox1.AppendText(vbCrLf & "=== 三连号检测结果 ===" & vbCrLf) If tripleResults.Count = 0 Then TextBox1.AppendText("范围内无三连号" & vbCrLf) Else For Each result In tripleResults TextBox1.AppendText(result & vbCrLf) Next End If
完整调用示例
把上述逻辑放到按钮的Click事件中即可:
Private Sub btnAnalyze_Click(sender As Object, e As EventArgs) Handles btnAnalyze.Click ' 1. 确定并校验范围 Dim startIndex = CInt(nudStartRow.Value) - 1 Dim endIndex = CInt(nudEndRow.Value) - 1 startIndex = Math.Max(0, startIndex) endIndex = Math.Min(ListBox1.Items.Count - 1, endIndex) If startIndex > endIndex Then MessageBox.Show("起始行不能大于结束行") Return End If ' 2. 执行单码统计 Dim singleCodeStats As New Dictionary(Of Integer, Integer)() For i = startIndex To endIndex Dim drawData = ParseDrawData(ListBox1.Items(i).ToString()) For Each num In drawData.numbers If singleCodeStats.ContainsKey(num) Then singleCodeStats(num) += 1 Else singleCodeStats(num) = 1 End If Next Next ' 3. 执行对子检测 Dim pairResults As New List(Of String)() For i = startIndex To endIndex Dim drawData = ParseDrawData(ListBox1.Items(i).ToString()) Dim foundPairs As New List(Of Integer)() For j = 0 To drawData.numbers.Count - 2 If drawData.numbers(j) = drawData.numbers(j + 1) Then If Not foundPairs.Contains(drawData.numbers(j)) Then foundPairs.Add(drawData.numbers(j)) End If End If Next If foundPairs.Count > 0 Then pairResults.Add($"期号{drawData.period}: 对子号码{String.Join(", ", foundPairs.Select(Function(n) n.ToString("D2")))}") End If Next ' 4. 执行三连号检测 Dim tripleResults As New List(Of String)() For i = startIndex To endIndex Dim drawData = ParseDrawData(ListBox1.Items(i).ToString()) Dim foundTriples As New List(Of String)() For j = 0 To drawData.numbers.Count - 3 If drawData.numbers(j + 1) = drawData.numbers(j) + 1 AndAlso drawData.numbers(j + 2) = drawData.numbers(j + 1) + 1 Then Dim tripleStr = $"{drawData.numbers(j).ToString("D2")}-{drawData.numbers(j+1).ToString("D2")}-{drawData.numbers(j+2).ToString("D2")}" foundTriples.Add(tripleStr) End If Next If foundTriples.Count > 0 Then tripleResults.Add($"期号{drawData.period}: 三连号{String.Join(", ", foundTriples)}") End If Next ' 5. 输出所有结果到TextBox TextBox1.Clear() TextBox1.AppendText("=== 单码出现统计 ===" & vbCrLf) For Each kvp In singleCodeStats.OrderBy(Function(x) x.Key) TextBox1.AppendText($"号码{kvp.Key.ToString("D2")}: {kvp.Value}次" & vbCrLf) Next TextBox1.AppendText(vbCrLf & "=== 对子检测结果 ===" & vbCrLf) If pairResults.Count = 0 Then TextBox1.AppendText("范围内无对子" & vbCrLf) Else For Each result In pairResults TextBox1.AppendText(result & vbCrLf) Next End If TextBox1.AppendText(vbCrLf & "=== 三连号检测结果 ===" & vbCrLf) If tripleResults.Count = 0 Then TextBox1.AppendText("范围内无三连号" & vbCrLf) Else For Each result In tripleResults TextBox1.AppendText(result & vbCrLf) Next End If End Sub
注意事项
- 号码排序是核心:排序后能大幅简化重复号码、连续号码的检测逻辑,避免遗漏或重复判断。
- 边界校验不可少:处理NumericUpDown输入时,必须确保索引在ListBox的有效范围内,防止数组越界错误。
- 格式统一:用
ToString("D2")将号码转为两位字符串,保证显示一致性(比如显示03而非3)。
内容的提问来源于stack exchange,提问作者GPU
相关产品推荐
相关产品推荐

