使用 for 循环在数组 C++ 中创建模式

Using for loops to make a pattern in an array C++

我正在尝试弄清楚如何使用嵌套 for 循环(如下所示)来初始化数组中的模式。现在我将所有值都设置为 1。所需的模式也在下面(在评论块中)。

/*{{1,1,1,1,1,1,1},
    { 1,2,2,2,2,2,1 },
    { 1,2,3,3,3,2,1 },
    { 1,2,3,4,3,2,1 },
    { 1,2,3,3,3,2,1 },
    { 1,2,2,2,2,2,1 },
    { 1,1,1,1,1,1,1 }};*/

据推测,我应该可以使用 abs(绝对值函数)来做到这一点。在制作代码的说明中,它说“库中的 abs 函数 return 是变量的绝对值。因此 abs(v-MIDDLE) 将 return v 与 MIDDLE 的距离。它将帮助您计算出您离数组中间有多远。"

有谁能帮我使用嵌套循环和 abs 函数来初始化正确的值吗?

void boardInit(Board board)
{
    for (int i = 0; i < BOARD_SIZE; ++i) 
    {
        for (int j = 0; j < BOARD_SIZE; ++j) 
        {
            board[i][j] = '1';
        }
    }
}

因此,您想要使用 2 个嵌套 for 循环创建以下模式。

1 1 1 1 1 1 1
1 2 2 2 2 2 1
1 2 3 3 3 2 1
1 2 3 4 3 2 1
1 2 3 3 3 2 1
1 2 2 2 2 2 1
1 1 1 1 1 1 1

总是有很多可能的解决方案来解决这样的问题。

先给大家讲解一个通俗易懂、更直观的做法

如果你查看给定的矩阵,你会发现数组中每个位置的值是到任何边界的最短距离。

因此,如果您查看由一行和一列组成的坐标,那么您可以数出您需要朝任何方向走多少步才能越过边界。然后,您可以计算最小距离并将此值写入矩阵。

例子。比方说,我们在第 3 行和第 3 列。(目前我忽略了我们在 C++ 中使用基于 0 的索引这一事实)。如果我们现在检查这个位置,那么您会注意到,我们需要向左走 3 步才能越过左边界。以及跨越右边界的 5 个步骤。所以,到左边的距离是 3,到右边的距离是 5。水平方向上的最小距离是 3。

垂直方向也可以这样做。

那么,在计算了垂直和水平的最小距离之后,我们就可以计算整体的最小距离了。并且,这个值我们将写入当前行和列的相应矩阵单元格。

因为在 C++ 中索引从 0 开始,我们需要将结果加 1 并计算边框的偏移量。

以上所有思考和理论设计的解决方案几乎可以一对一地实现到代码中。

可能的解决方案如下所示

#include <iostream>
#include <array>
#include <algorithm>

int main() {
    // Chosse any matrix size here
    constexpr size_t MatrixSize = 7u;

    // A 2-dimensional array of integers
    std::array<std::array<int, MatrixSize>, MatrixSize> matrix{};

    // Iterate over all row and oclumns
    for (size_t row{}; row < MatrixSize; ++row) {
        for (size_t column{}; column < MatrixSize; ++column) {

            // So, now, for the current coordinate consisting of row and column

            // Get the distance to a horizontal border
            const int distanceToLeft = column - 0;
            const int distanceToRight = (MatrixSize-1) - column;

            // What is the shortest way horizontally
            const int minimumDistanceHorizontally = std::min(distanceToLeft, distanceToRight);

            // Get the distance to a vertical border
            const int distanceToTop = row - 0;
            const int distanceToBottom = (MatrixSize-1) - row;

            // What is the shortest vertically
            const int minimumDistanceVertically = std::min(distanceToTop, distanceToBottom);

            // What is the shortest way overall
            const int minimumDistanceToAnyBorder = std::min(minimumDistanceHorizontally, minimumDistanceVertically);

            // Set value
            matrix[row][column] = minimumDistanceToAnyBorder + 1;
        }
    }
    for (const auto& row : matrix) {
        for (const int i : row) std::cout << i << ' ';
        std::cout << '\n';
    }
}

分析这段代码可以看到,所有的中间计算都是const,永远不会改变

因此,您可以在一行中重构所有中间计算。

matrix[row][column] = 1 + std::min(std::min(column, MatrixSize-1-column),std::min(row, MatrixSize - 1 - row));

但是,那么,以后就没有人会理解这个复杂的公式了。所以,冗长的形式最终更好。相信我,现代优化编译器将从中生成最好的代码。

该示例应该说明如何解决此类问题。

编辑

以下方法可用于计算基于矩阵中间的值。

同样在这里,我们从行和列索引开始。让我们看一个 8*8 的矩阵。

那么索引,无论是水平方向还是垂直方向,对于列和行,都是:

0    1    2    3     4     5     6     7

中间值,不幸的是,在这种情况下,浮点数将是 3,5。那么,接下来,我们就可以简单的计算行或列到中间值的距离。结果将是(中间值 - 坐标)。

3.5  2.5  1.5  0.5  -0.5  -1.5  -2.5  -3.5

因为我们对负值不感兴趣,所以我们取abs函数然后得到:

3.5  2.5  1.5  0.5   0.5   1.5   2.5   3.5

但是我们想要得到反距离,那么中间的值有多近。所以,我们再次从中间值中减去那些中间结果,结果是:

0    1    2    3     3     2     1     0

然后,和第一个例子一样,我们取垂直和水平方向的最小值,然后加 1 以显示所需的输出。

请看这里

#include <iostream>
#include <array>
#include <algorithm>

int main() {
    // Chosse any matrix size here
    constexpr size_t MatrixSize = 7u;

    // A 2-dimensional array of integers
    std::array<std::array<int, MatrixSize>, MatrixSize> matrix{};

    // Iterate over all row and oclumns
    for (size_t row{}; row < MatrixSize; ++row) {
        for (size_t column{}; column < MatrixSize; ++column) {

            // So, now, for the current coordinate consisting of row and column
            // Get the middle Value
            const double middle = (MatrixSize-1) / 2.0;

            // Get the distance from the middle value horizontally
            const int distanceHorizontally = static_cast<int>(middle - std::abs(middle - column));

            // Get the distance from the middle value horizontally
            const int distanceVertically = static_cast<int>(middle - std::abs(middle - row));

            // Get the shortest distance from middle overall
            const int minimumDistanceMiddleOverall = std::min(distanceHorizontally, distanceVertically);

            // Set value
            matrix[row][column] = minimumDistanceMiddleOverall + 1;
        }
    }
    for (const auto& row : matrix) {
        for (const int i : row) std::cout << i << ' ';
        std::cout << '\n';
    }
}

我个人觉得第一种方法更直观,但是,随心所欲。

如有问题,请提出,我很乐意提供帮助