为何使用嵌套foreach循环?求C#嵌套foreach循环逻辑解析
拆解嵌套foreach:从数独代码里搞懂逻辑
嘿,我太懂嵌套foreach一开始那种“绕得脑壳疼”的感觉了——咱们别盯着术语看,直接拿你这段数独文件读取的代码当例子,一步一步拆,保证你能摸透它的逻辑!
先搞懂:嵌套foreach到底是啥?
你可以把它想象成生活里的“两步遍历”:比如你要整理书架,**第一步(外层循环)**先从左到右遍历每一层书架;**第二步(内层循环)**在每一层里,再从左到右遍历每一本书。放到代码里,就是先遍历一个“大集合”(比如文件的所有行),然后对大集合里的每一个元素(比如某一行),再遍历它内部的“小集合”(比如这一行里的所有数独格子)。
拆解你的数独代码嵌套逻辑
咱们把代码拆成块,对应着每一步的逻辑来看:
带注释的完整代码
class SudokuFileReader { public int[,] ReadFile(string fileName) { // 初始化一个9x9的二维数组,用来存数独数据 int[,] sudokuBoard = new int[9, 9]; try { // 把整个数独文件的内容按行读成字符串数组,每一行就是sudokuBoardLines里的一个元素 var sudokuBoardLines = File.ReadAllLines(fileName); int row = 0; // 记录当前正在处理的数独行号,从第0行开始 // 👉 外层foreach:遍历文件的每一行,对应数独的每一行 foreach (var sudokuBoardLine in sudokuBoardLines) { // 把当前行的字符串按|分割,跳过第一个元素(因为文件里的行可能是|1|2|3|...这种格式),只取前9个元素(数独是9列) string[] sudokuBoardLineElements = sudokuBoardLine.Split('|').Skip(1).Take(9).ToArray(); int col = 0; // 记录当前正在处理的数列号,从第0列开始 // 👉 内层foreach:遍历当前行的每一个格子元素,对应数独的每一列 foreach (var sudokuLineElement in sudokuBoardLineElements) { // 如果元素是空格,就存0;否则转成数字存到数组对应的位置 sudokuBoard[row, col] = sudokuLineElement.Equals(" ") ? 0 : Convert.ToInt16(sudokuLineElement); col++; // 列号加1,处理下一个格子 } row++; // 行号加1,处理下一行 } } catch (Exception ex) { throw new Exception("Something went wrong while reading the file: " + ex.Message); } return sudokuBoard; } }
逐步走一遍流程
假设你的数独文件里有这样一行:| |3| |...(省略其他列),咱们跟着循环走:
- 外层循环第一次迭代:拿到这一行,
row=0 - 把这一行分割成数组,跳过第一个空元素,得到
[" ", "3", ...]这样的9个元素 - 内层循环开始:
- 第一个元素是
" ",所以sudokuBoard[0,0] = 0,col变成1 - 第二个元素是
"3",所以sudokuBoard[0,1] = 3,col变成2 - ... 一直处理完这9个元素,
col变成9,内层循环结束
- 第一个元素是
row变成1,外层循环处理下一行,重复上面的步骤
核心逻辑总结
嵌套foreach的本质就是**“先搞定一行,再搞定这一行里的每一个格子”**——完全和你手动填数独的顺序一模一样:先看第一行,从左到右填每个格子;填完第一行,再看第二行,同样从左到右填。
只要记住:外层循环管“大维度”(比如行),内层循环管“小维度”(比如列),就再也不会绕晕啦!
内容的提问来源于stack exchange,提问作者Breath
相关产品推荐
相关产品推荐

