Bingo棋盘无重复数字代码编译成功但控制台无输出问题排查
Bingo棋盘重复检查问题分析与优化
问题分析
1. 控制台无输出原因
你仅实现了PopulateCard方法,但未在主程序中调用它,也没有编写输出棋盘内容的代码,因此运行后控制台没有任何输出。
2. CheckDouble方法的逻辑错误
- 参数传反:调用
CheckDouble(counter, num)时,参数顺序与方法定义CheckDouble(int num, int counter)完全颠倒,导致方法内变量逻辑混乱,无法正确对应已生成的数字和计数。 - 无法记录历史数字:每次调用
CheckDouble都会新建一个int[25]数组,数组默认值全为0,仅当前赋值的nums[counter] = num有效,之前生成的数字从未被存储,遍历检查完全无效,起不到去重作用。
3. 原逻辑的效率问题
即便修复上述问题,用数组存储已生成数字并逐个遍历检查的方式,时间复杂度为O(n²),填充到后期(如第24个数字)时,需要多次随机+遍历检查,效率会越来越低。
优化方案
1. 修复输出问题
在主方法中调用PopulateCard,并添加输出棋盘的方法:
static void PrintCard() { for (int row = 0; row < card.GetLength(0); row++) { for (int col = 0; col < card.GetLength(1); col++) { Console.Write($"{card[row, col],3}"); } Console.WriteLine(); } } // 主方法中调用 static void Main() { PopulateCard(); PrintCard(); }
2. 重构去重逻辑,提升效率
使用HashSet<int>记录已生成数字,检查重复的时间复杂度为O(1),大幅提升效率,同时简化代码逻辑:
static int[,] card = new int[5, 5]; static Random rand = new Random(); static HashSet<int> usedNumbers = new HashSet<int>(); static void PopulateCard() { for (int row = 0; row < card.GetLength(0); row++) { for (int col = 0; col < card.GetLength(1); col++) { // 中间格固定为0,无需随机和去重 if (row == 2 && col == 2) { card[row, col] = 0; continue; } int num; do { // 根据列生成对应范围的随机数 num = col switch { 0 => rand.Next(1, 16), 1 => rand.Next(16, 31), 2 => rand.Next(31, 46), 3 => rand.Next(46, 61), _ => rand.Next(61, 76) }; } // HashSet.Add会自动判断是否重复,重复返回false,否则添加并返回true while (!usedNumbers.Add(num)); card[row, col] = num; } } } static void PrintCard() { for (int row = 0; row < card.GetLength(0); row++) { for (int col = 0; col < card.GetLength(1); col++) { Console.Write($"{card[row, col],3}"); } Console.WriteLine(); } } static void Main() { PopulateCard(); PrintCard(); }
优化点说明
- HashSet高效去重:利用
HashSet<int>.Add的返回值直接控制循环,无需额外编写检查方法,逻辑简洁且检查操作是O(1)时间复杂度。 - 简化列范围判断:使用C# switch表达式替代多个else if,代码可读性更强。
- 分离特殊逻辑:提前处理中间格的0,避免进入随机和去重循环,减少无效操作。
- 添加输出方法:实现
PrintCard将棋盘内容输出到控制台,解决无输出问题。
内容的提问来源于stack exchange,提问作者iLuvSoftware
相关产品推荐
相关产品推荐

