【问题标题】:How can I make nested loop by using only one for loop?如何仅使用一个 for 循环来制作嵌套循环?
【发布时间】:2022-01-13 14:34:28
【问题描述】:

我从堆栈溢出中看到了这段代码

int[,] matrix = new int[5, 10];     
int row = matrix.GetLength(0);
int col = matrix.GetLength(1);      

for (int i = 0; i < row * col; i++)
{
    matrix[i / col , i % col] = i + 1;
}

有人说它会产生嵌套循环。 我试图破解这个密码,但我做不到。 有人请解释一下这段代码是如何工作的。

【问题讨论】:

  • 避免嵌套循环有什么好处?
  • @SteveB 在这种情况下,没有。但在某些情况下,它可以线性化对底层连续存储的访问。在 C++ 中,将多维数组实现为一维向量是一种相当常见的技术。我相信在 C# 中执行像素级图像处理时(可以想象在实现图像过滤器时)也是如此。

标签: c# for-loop


【解决方案1】:

从技术上讲,这段代码本身没有嵌套循环。但是,它从0 计数到5 * 10 - 1,并且在每次迭代中计算行和列索引。以下内容可能更容易理解:

for (int i = 0; i < row * col; i++)
{
    int rowIndex = i / col; // divide by column count = row index
    int colIndex = i % col; // modulo by column count = column index
    Console.WriteLine($"i: {i} => row: {rowIndex}, col: {colIndex}");
    matrix[rowIndex, colIndex] = i + 1;
}

写下实际数字,您会亲眼看到,对于 09 的迭代,您将得到 rowIndex == 0colIndex 的值 09,然后对于迭代 1019 你会得到 rowIndex == 1colIndex 的值 09 等等。

嵌套循环变体自然会如下所示:

for (int rowIndex = 0; rowIndex < row; rowIndex++)
{
  for (int colIndex = 0; colIndex < col; colIndex++)
  {
    int i = rowIndex * col + colIndex; // back-calculate 'i'
    Console.WriteLine($"i: {i} => row: {rowIndex}, col: {colIndex}");
    matrix[rowIndex, colIndex] = i + 1;
}

单循环版本具有嵌套外观展开,取而代之的是数学运算(除法、取模)。

【讨论】:

    【解决方案2】:

    如果您有两个嵌套的for 循环,一个从0 到row,一个从0 到col,这两个循环将一起执行row * col 次。因此,您可以将嵌套循环替换为从 0 到 row * col 的单个循环,这正是这里所做的。

    您唯一需要做的就是从单个循环索引i 中找到嵌套循环的单独循环索引(我们称它们为jk)。

    执行此操作的方法是考虑使用数字 0…row * col 填充的 row * col 表。我们如何找到给定条目i 的行和列索引(分别为jk)?好吧,您发布的代码告诉我们:

    int j = i / col // row index
    int k = i % col // col index
    

    【讨论】:

      猜你喜欢
      • 2021-12-11
      • 1970-01-01
      • 2020-07-19
      • 2021-09-15
      • 2019-04-15
      • 2013-08-04
      • 2022-06-15
      • 2018-07-13
      • 1970-01-01
      相关资源
      最近更新 更多