如何验证Lo Shu Magic Square输入的二维数组无重复值?
问题
在第一门编程课中实现Lo Shu Magic Square时遇到瓶颈。Lo Shu Magic Square是3x3二维数组,要求用户输入9个1-9之间且不重复的数字。已完成输入值的范围验证,但卡在重复值验证环节。以下是获取用户输入的函数代码:
// Get numbers void getNumbers(int magicSquare[][COLS], int ROWS) { cout << "\nEnter Nine Numbers (1-9)" << endl; int num; int n = 0; for (int r = 0; r < ROWS; r++) { for (int c = 0; c < COLS; c++) { cout << "\tNumber " << (n + 1) << ": "; cin >> num; magicSquare[r][c] = num; n++; // Input validation // Validate against numbers outside the range while (num < 1 || num > 9) { cout << "\tError ... Invalid number. Try again" << endl << endl; cout << "\tNumber " << (n) << ": "; cin >> num; magicSquare[r][c] = num; } // Validate against repeating numbers while (...) //OMEGA STUCK { cout << "\tError ... " << num << " is already in the Lo Shu Square. Try again" << endl <<endl; cout << "\tNumber " << (n) << ": "; cin >> num; magicSquare[r][c] = num; } } } cout << endl; }
尝试过while循环、临时数组等方法,目前尝试用布尔函数检测重复值但效果不佳,还出现数组越界错误,相关代码如下:
// Validate against repeating numbers while (repeatNumbers(magicSquare, num)) // Calling boolean function (defined below) { cout << "\tError ... " << num << " is already in the Lo Shu Square. Try again" << endl << endl; cout << "\tNumber " << (n) << ": "; cin >> num; magicSquare[r][c] = num; } ... // Validate against repeating numbers function bool repeatNumbers(int magicSquare[][COLS], int num) { bool status; if (num == magicSquare[COLS][COLS]) //Here I get an error: { //"Reading invalid data from status = true; //'magicSquare[COLS]'. } else { status = false; } return status; }
请问如何确保读取部分填充的数组安全,同时验证输入值范围和无重复值的最佳方案是什么?
解决方案
核心问题分析
你当前的重复检测函数只检查了magicSquare[COLS][COLS],这属于数组越界(3x3数组的索引范围是0-2,COLS若为3则索引3超出边界),且完全没有遍历已输入的元素,根本起不到重复检测作用。另外,现有逻辑是先将输入存入数组再验证,会导致无效值污染数组,增加误判风险。
优化方案
方案1:遍历已输入元素(无需额外数据结构)
通过记录已输入的有效数字数量,仅遍历数组中已填充的部分,避免访问未初始化的元素:
void getNumbers(int magicSquare[][COLS], int ROWS) { cout << "\nEnter Nine Numbers (1-9)" << endl; int num; int validCount = 0; // 记录已输入的有效数字数量 for (int r = 0; r < ROWS; r++) { for (int c = 0; c < COLS; c++) { bool isValid = false; while (!isValid) { cout << "\tNumber " << (validCount + 1) << ": "; cin >> num; // 第一步:验证输入范围 if (num < 1 || num > 9) { cout << "\tError ... Invalid number. Try again\n" << endl; continue; } // 第二步:验证重复值 bool isDuplicate = false; // 仅遍历已输入的validCount个元素 for (int i = 0; i < validCount; i++) { int row = i / COLS; int col = i % COLS; if (magicSquare[row][col] == num) { isDuplicate = true; break; } } if (isDuplicate) { cout << "\tError ... " << num << " is already in the Lo Shu Square. Try again\n" << endl; continue; } // 验证通过,存入数组并更新计数 magicSquare[r][c] = num; validCount++; isValid = true; } } } cout << endl; }
方案2:用布尔数组标记已使用数字(更高效)
利用输入范围固定为1-9的特点,用大小为10的布尔数组直接标记数字是否已被使用,重复检测时间复杂度为O(1):
void getNumbers(int magicSquare[][COLS], int ROWS) { cout << "\nEnter Nine Numbers (1-9)" << endl; int num; bool used[10] = {false}; // 索引0弃用,1-9对应数字的使用状态 int validCount = 0; for (int r = 0; r < ROWS; r++) { for (int c = 0; c < COLS; c++) { bool isValid = false; while (!isValid) { cout << "\tNumber " << (validCount + 1) << ": "; cin >> num; // 范围验证 if (num < 1 || num > 9) { cout << "\tError ... Invalid number. Try again\n" << endl; continue; } // 重复验证 if (used[num]) { cout << "\tError ... " << num << " is already in the Lo Shu Square. Try again\n" << endl; continue; } // 验证通过,标记状态并存入数组 used[num] = true; magicSquare[r][c] = num; validCount++; isValid = true; } } } cout << endl; }
关键改进点
- 调整验证顺序:先验证输入有效性,再写入数组,避免无效值污染数组。
- 安全访问部分填充数组:方案1通过计数控制遍历范围,方案2完全规避遍历原数组,彻底避免越界问题。
- 简化重复检测逻辑:两种方案都能准确检测已输入的重复值,方案2在效率上更优。
内容的提问来源于stack exchange,提问作者Clemente
相关产品推荐
相关产品推荐

