遍历二维矩阵对角线省略第一行和第一列
Traverse 2D Matrix diagonally omitting first row and first column
我正在尝试对角遍历一个二维矩阵,下面的函数打印了一个 diagonal.I 中的所有元素想跳过第一行和第一列元素并从矩阵[1][1开始对角遍历] 因为第 0 行和第 0 列中的值不是 required.So 这就像从顶部切片矩阵并从 [1][1] 开始但不对矩阵底部进行任何更改。
void diagonalOrder(int matrix[][COL])
{
for(int line = 1;
line <= (ROW + COL - 1);
line++)
{
int start_col = max(0, line - ROW);
int count = min(line, (COL - start_col), ROW);
/* Print elements of this line */
for(int j = 0; j < count; j++)
cout << setw(5) <<
matrix[minu(ROW, line) - j - 1][start_col + j];
cout << "\n";
}
我将用示例更新我的问题,使其 clear.Consider 成为以下矩阵。
0 1 2 3 4
matrix[5][5] = 1 8 5 3 1
2 4 5 7 1
3 6 4 3 2
4 3 4 5 6
以上函数将打印对角线的值。
Output:
0
1 1
2 8 2
3 4 5 3
4 6 5 3 4
3 4 7 1
4 3 1
5 2
6
我想跳过第一行第一列的元素,从矩阵[1]开始[1]想对角遍历矩阵
Desired Output:
8
4 5
6 5 3
3 4 7 1
4 3 1
5 2
6
我真的不明白你的代码试图做什么,只是按照你需要迭代具有相等行和列索引的数组项的描述,直到没有更多的行或没有更多的列,即
void print_tail_of_diagonal(int matrix[ROWS][COLS])
{
int n = std::min(ROWS, COLS);
for (int i = 1; i < n; ++i) {
std::cout << matrix[i][i] << " ";
}
std::cout << "\n";
}
从你的例子看来你想要打印反对角线而不是对角线,即第三行是 3 4 5 3
而不是 3 5 4 3
.
开始时保持简单:沿着反对角线的索引 (i,j)
是那些 i
和 j
,其中 i+j == some_constant
。因此,这是一种沿反对角线打印元素的简单(效率不高)方法:
void print_antidiagonal(int matrix[5][5],int x){
for (int i=4;i >= 0; --i) {
for (int j=0;j < 5; ++j) {
if (i+j == x) std::cout << matrix[i][j] << " ";
}
}
std::cout << "\n";
}
此外还有 nrows + (ncols-1)
个反对角线,因此您可以通过以下方式打印它们:
for (int i=0;i < 5+4; ++i) {
print_antidiagonal(matrix,i);
}
上面的函数效率不是很高,但是很简单。很明显如何跳过第一行和第一列:
for (int i=4;i >= 1; --i) { // loop till 1 instead of 0
for (int j=1;j < 5; ++j) { // loop from 1 instead of 0
这足以产生所需的输出 (https://godbolt.org/z/7KWjb7qh7)。然而,上述不仅效率低下,而且代码也不是很清楚其意图。 print_antidiagonal
沿单个 anti-diagonal 打印元素,因此迭代所有矩阵元素是一个糟糕的惊喜。
我建议打印索引而不是矩阵元素,以便更好地了解模式 (https://godbolt.org/z/TnrbbY4jM):
1,1
2,1 1,2
3,1 2,2 1,3
4,1 3,2 2,3 1,4
4,2 3,3 2,4
4,3 3,4
4,4
同样,在每一行中 i+j
是一个常量。该常量在每一行中递增 1
。在每一行中,i
递减而 j
递增,直到 i == 1
或 j==4
。第一个元素是 i
最大且 j = constant - i
.
因此:
void print_antidiagonal(int matrix[5][5],int x){
int i = std::min(x-1,4);
int j = x - i;
while (i >= 1 && j <= 4) {
std::cout << matrix[i][j] << " ";
--i;
++j;
}
std::cout << "\n";
}
PS:我使用硬编码索引,因为我认为遵循逻辑更简单。对于更现实的解决方案,矩阵大小和偏移当然应该参数化。
我正在尝试对角遍历一个二维矩阵,下面的函数打印了一个 diagonal.I 中的所有元素想跳过第一行和第一列元素并从矩阵[1][1开始对角遍历] 因为第 0 行和第 0 列中的值不是 required.So 这就像从顶部切片矩阵并从 [1][1] 开始但不对矩阵底部进行任何更改。
void diagonalOrder(int matrix[][COL])
{
for(int line = 1;
line <= (ROW + COL - 1);
line++)
{
int start_col = max(0, line - ROW);
int count = min(line, (COL - start_col), ROW);
/* Print elements of this line */
for(int j = 0; j < count; j++)
cout << setw(5) <<
matrix[minu(ROW, line) - j - 1][start_col + j];
cout << "\n";
}
我将用示例更新我的问题,使其 clear.Consider 成为以下矩阵。
0 1 2 3 4
matrix[5][5] = 1 8 5 3 1
2 4 5 7 1
3 6 4 3 2
4 3 4 5 6
以上函数将打印对角线的值。
Output:
0
1 1
2 8 2
3 4 5 3
4 6 5 3 4
3 4 7 1
4 3 1
5 2
6
我想跳过第一行第一列的元素,从矩阵[1]开始[1]想对角遍历矩阵
Desired Output:
8
4 5
6 5 3
3 4 7 1
4 3 1
5 2
6
我真的不明白你的代码试图做什么,只是按照你需要迭代具有相等行和列索引的数组项的描述,直到没有更多的行或没有更多的列,即
void print_tail_of_diagonal(int matrix[ROWS][COLS])
{
int n = std::min(ROWS, COLS);
for (int i = 1; i < n; ++i) {
std::cout << matrix[i][i] << " ";
}
std::cout << "\n";
}
从你的例子看来你想要打印反对角线而不是对角线,即第三行是 3 4 5 3
而不是 3 5 4 3
.
开始时保持简单:沿着反对角线的索引 (i,j)
是那些 i
和 j
,其中 i+j == some_constant
。因此,这是一种沿反对角线打印元素的简单(效率不高)方法:
void print_antidiagonal(int matrix[5][5],int x){
for (int i=4;i >= 0; --i) {
for (int j=0;j < 5; ++j) {
if (i+j == x) std::cout << matrix[i][j] << " ";
}
}
std::cout << "\n";
}
此外还有 nrows + (ncols-1)
个反对角线,因此您可以通过以下方式打印它们:
for (int i=0;i < 5+4; ++i) {
print_antidiagonal(matrix,i);
}
上面的函数效率不是很高,但是很简单。很明显如何跳过第一行和第一列:
for (int i=4;i >= 1; --i) { // loop till 1 instead of 0
for (int j=1;j < 5; ++j) { // loop from 1 instead of 0
这足以产生所需的输出 (https://godbolt.org/z/7KWjb7qh7)。然而,上述不仅效率低下,而且代码也不是很清楚其意图。 print_antidiagonal
沿单个 anti-diagonal 打印元素,因此迭代所有矩阵元素是一个糟糕的惊喜。
我建议打印索引而不是矩阵元素,以便更好地了解模式 (https://godbolt.org/z/TnrbbY4jM):
1,1
2,1 1,2
3,1 2,2 1,3
4,1 3,2 2,3 1,4
4,2 3,3 2,4
4,3 3,4
4,4
同样,在每一行中 i+j
是一个常量。该常量在每一行中递增 1
。在每一行中,i
递减而 j
递增,直到 i == 1
或 j==4
。第一个元素是 i
最大且 j = constant - i
.
因此:
void print_antidiagonal(int matrix[5][5],int x){
int i = std::min(x-1,4);
int j = x - i;
while (i >= 1 && j <= 4) {
std::cout << matrix[i][j] << " ";
--i;
++j;
}
std::cout << "\n";
}
PS:我使用硬编码索引,因为我认为遵循逻辑更简单。对于更现实的解决方案,矩阵大小和偏移当然应该参数化。