使用连续数字C ++填充2d数组之字形

时间:2017-11-14 03:17:35

标签: c++ arrays

我坚持这个。你能帮我吗?

编写一个初始化二维数组的函数。阵列是方形的 矩阵(即,它的宽度和高度是相同的。)阵列应该初始化 之字形风格。具体来说,我们从左上角开始向下,然后放一个
数字从1开始。一旦我们到达底部,我们转到下一列并填写
从下到上的数字。我们在第三个中填写数字 列,在第四列中向上,依此类推。所有的过程都结束了 数组中的元素被填充。

However, How do I get my output like this?
1 10 11 20 21
2 9 12 19 22
3 8 13 18 23
4 7 14 17 24
5 6 15 16 25

#include <iomanip>
#include <iostream>
using namespace std;
const int SIZE = 5; // Note SIZE can be anything between 1 to 9
void initGrid(int grid[SIZE][SIZE]);
void printGrid(int grid[SIZE][SIZE]);
int main() {
    int grid[SIZE][SIZE];
    initGrid(grid);
    printGrid(grid);
}
void initGrid(int grid[SIZE][SIZE]) {
    int inc = 1;
    for (int j = 0; j < SIZE; j++) {
        for (int i = 0; i < SIZE; i++) {
             grid[i][j] = inc;
             inc++;
        }
    }
}
void printGrid(int grid[SIZE][SIZE]) {
    for (int i = 0; i < SIZE; i++) {
        for (int j = 0; j < SIZE; j++) {
            // setw() function handles the printing format.
            cout << setw(2) << grid[i][j] << " ";
        }
        cout << endl;
    }
}

2 个答案:

答案 0 :(得分:1)

网格的每两列共享相同的填充模式,奇数按照升序填充,偶数按降序填充。您所要做的就是将其转换为代码:

template<size_t Rows, size_t Cols>
void initGrid(int (&grid)[Rows][Cols]) {
    int value = 1;
    for (size_t j = 0; j < Cols; ++j) {
        // first fill the odd column in descending order
        for (size_t i = 0; i < Rows; ++i, ++value) {
            grid[i][j] = value;
        }
        // then, if there is one, fill the even column
        ++j;
        if (j == Cols )
            break;
        for (size_t i = Rows; i > 0; ++value) {
            --i;   // size_t is unsigned, so I have to check i before decrementing
            grid[i][j] = value;
        }
    }
}

我使用了你使用的相同数据结构(但是不同的函数签名)只关注算法,但我会改用类。

如果您不希望逐列遍历数组(对于 big 数组,可能会因缓存未命中而导致性能下降),您可以计算每行中值之间的差异:

template<size_t Rows, size_t Cols>
void zig_zag_fill(int (&grid)[Rows][Cols])
{
    int diff_up = 1;
    int diff_down = Rows * 2 - 1;
    for (size_t i = 0; i < Rows; ++i, diff_down -= 2, diff_up += 2)
    {
        int value = i + 1;
        size_t j = 0;
        while ( j < Cols )
        {
            grid[i][j] = value;
            value += diff_down;
            ++j;
            if ( j == Cols )
                break;
            grid[i][j] = value;
            value += diff_up;
            ++j;
        }
    }
}

这样一个完整的测试程序:

#include <iostream>
#include <iomanip>

template<size_t Rows, size_t Cols>
void zig_zag_fill(int (&grid)[Rows][Cols]);

template<size_t Rows, size_t Cols>
void printGrid(int (&grid)[Rows][Cols]);

int main() {
    int grid[5][6];
    zig_zag_fill(grid);
    printGrid(grid);
    std::cout << '\n';
    int grid2[6][5];
    zig_zag_fill(grid2);
    printGrid(grid2);
    std::cout << '\n';
    int grid3[5][5];
    zig_zag_fill(grid3);
    printGrid(grid3);
    std::cout << '\n';
    int grid4[6][6];
    zig_zag_fill(grid4);
    printGrid(grid4);
    std::cout << '\n';
}

template<size_t Rows, size_t Cols>
void initGrid(int (&grid)[Rows][Cols]) {
    int value = 1;
    for (size_t j = 0; j < Cols; ++j) {
        for (size_t i = 0; i < Rows; ++i, ++value) {
            grid[i][j] = value;
        }
        ++j;
        if (j == Cols )
            break;
        for (size_t i = Rows; i > 0; ++value) {
            --i;
            grid[i][j] = value;
        }
    }
}

template<size_t Rows, size_t Cols>
void zig_zag_fill(int (&grid)[Rows][Cols])
{
    int diff_up = 1;
    int diff_down = Rows * 2 - 1;
    for (size_t i = 0; i < Rows; ++i, diff_down -= 2, diff_up += 2)
    {
        int value = i + 1;
        size_t j = 0;
        while ( j < Cols )
        {
            grid[i][j] = value;
            value += diff_down;
            ++j;
            if ( j == Cols )
                break;
            grid[i][j] = value;
            value += diff_up;
            ++j;
        }
    }
}


template<size_t Rows, size_t Cols>
void printGrid(int (&grid)[Rows][Cols]) {
    for (size_t i = 0; i < Rows; ++i) {
        for (size_t j = 0; j < Cols; ++j) {
            std::cout << std::setw(2) << grid[i][j] << " ";
        }
        std::cout << '\n';
    }
}

输出:

 1 10 11 20 21 30 
 2  9 12 19 22 29 
 3  8 13 18 23 28 
 4  7 14 17 24 27 
 5  6 15 16 25 26 

 1 12 13 24 25 
 2 11 14 23 26 
 3 10 15 22 27 
 4  9 16 21 28 
 5  8 17 20 29 
 6  7 18 19 30 

 1 10 11 20 21 
 2  9 12 19 22 
 3  8 13 18 23 
 4  7 14 17 24 
 5  6 15 16 25 

 1 12 13 24 25 36 
 2 11 14 23 26 35 
 3 10 15 22 27 34 
 4  9 16 21 28 33 
 5  8 17 20 29 32 
 6  7 18 19 30 31 

答案 1 :(得分:0)

首先,如果我正在编写这个程序,我将以不同的方式表示我的数据。即我可能会使用向量并避免全局大小常量。有人说,这是我将如何做到这一点。让我们写出索引所遵循的序列,并试着看看我们是否可以创建某种序列。

1 4 7
2 5 8
3 6 9

创建它之后是否在数组中,我们想要

1 6 7
2 5 8
3 4 9

我们对原始数组的索引如下所示

(0, 0) (2, 1) (0, 2)
(1, 0) (1, 1) (1, 2)
(2, 0) (0, 1) (2, 2)

我们的j组件很简单,它只是一个简单的算术序列,你可以加1,即1,2,3,4,5 ......

for (int j = 0; j < 3; j++){
  ...
}

现在我们需要一个遵循patten 0,1,2,1,0,0,1,2,......重复的序列。由于我们有重复的数字,我正在考虑时钟算术或模运算。让我们从序列0,1,2,0,1,2 ......重复开始。即整数mod 3(Z mod 3)。对于第一列,我们希望指标直接向上(Z mod 3)。然后对于反向列,假设我们给出了这个序列,我们从0到2迭代它。我们可以巧妙地使用模运算来得到我们的反向序列。例如,如果我们有(2 mod 3),(4 mod 3),(6 mod 3),我们将得到2,1,0。我们如何得到0,1,2到2,4,6?像这样f(x):( x + 1)* 2.

bool reversed = false;
for (int i = 0; i < 3; i++){
    int idx = i;
    if(reversed){
      int offset = (i + 1) * 2;
      idx = (offset) % 3;
    }
}
reversed = !reversed;

现在我们必须把它们放在一起。这应该是我们新的初始网格,因为打印功能很好。

for (int j = 0; j < SIZE; j++){
  bool reversed = false;
  for (int i = 0; i < SIZE; i++){
    int idx = i;
    if(reversed){
      int offset = (i + 1) * (SIZE - 1);
      idx = (offset) % SIZE;
    }
    arr[idx][j] = inc;
    inc++;
  }
  reversed = !reversed;
}

应该这样做。我让它在repl.it中工作,希望这会有所帮助。