我坚持这个。你能帮我吗?
编写一个初始化二维数组的函数。阵列是方形的
矩阵(即,它的宽度和高度是相同的。)阵列应该初始化
之字形风格。具体来说,我们从左上角开始向下,然后放一个
数字从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;
}
}
答案 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中工作,希望这会有所帮助。