Для быстрой и грязной фиксации иногда я просто прокручиваю вверх и вниз, и выделение приспосабливается. Ctrl + L для экранной перерисовки может также зафиксировать его.
Вот кое-что, что вы можете использовать. Просто замените printfs тем, что вы действительно хотите сделать.
#include <stdio.h>
int main()
{
int x[3][3] = {1, 2, 3,
4, 5, 6,
7, 8, 9};
int n = 3;
for (int slice = 0; slice < 2 * n - 1; ++slice) {
printf("Slice %d: ", slice);
int z = (slice < n) ? 0 : slice - n + 1;
for (int j = z; j <= slice - z; ++j) {
printf("%d ", x[j][slice - j]);
}
printf("\n");
}
return 0;
}
Вывод:
Slice 0: 1
Slice 1: 2 4
Slice 2: 3 5 7
Slice 3: 6 8
Slice 4: 9
вам нужно разбить матрицу на верхнюю и нижнюю части и перебирать каждую из них отдельно, сначала одну половину строки, сначала другой столбец. предположим, что матрица n * n, хранится в векторе, первая строка, нулевое основание, циклы исключают последний элемент.
for i in 0:n
for j in 0:i +1
A[i + j*(n-2)]
the other half can be done in a similar way, starting with:
for j in 1:n
for i in 0:n-j
... each step is i*(n-2) ...
Я бы, вероятно, сделал что-то вроде этого (заранее извиняюсь за любые ошибки индекса, не отлаживал это):
// Operation to be performed on each slice:
void doSomething(const int lengthOfSlice,
elementType *slice,
const int stride) {
for (int i=0; i<lengthOfSlice; ++i) {
elementType element = slice[i*stride];
// Operate on element ...
}
}
void operateOnSlices(const int n, elementType *A) {
// distance between consecutive elements of a slice in memory:
const int stride = n - 1;
// Operate on slices that begin with entries in the top row of the matrix
for (int column = 0; column < n; ++column)
doSomething(column + 1, &A[column], stride);
// Operate on slices that begin with entries in the right column of the matrix
for (int row = 1; row < n; ++row)
doSomething(n - row, &A[n*row + (n-1)], stride);
}
Псевдокод:
N = 2 // or whatever the size of the [square] matrix
for x = 0 to N
strip = []
y = 0
repeat
strip.add(Matrix(x,y))
x -= 1
y -= 1
until x < 0
// here to print the strip or do some' with it
// And yes, Oops, I had missed it...
// the 2nd half of the matrix...
for y = 1 to N // Yes, start at 1 not 0, since main diagonal is done.
strip = []
x = N
repeat
strip.add(Matrix(x,y))
x -= 1
y += 1
until x < 0
// here to print the strip or do some' with it
(Предполагается, что x индексирует строки, y индексирует столбцы,
Я бы сдвинул строки следующим образом:
1 2 3 x x
x 4 5 6 x
x x 7 8 9
И просто перебрал столбцы. На самом деле это можно сделать без физического переключения.
Ключ состоит в том, чтобы перебрать каждый элемент в первой строке и от нее идти вниз по диагонали. Затем повторите каждый элемент в последнем столбце (без первого, который мы прошли на предыдущем шаге), а затем спуститесь по его диагонали.
Вот исходный код, который предполагает, что матрица является квадратной матрицей (непроверенной, переведенной из рабочей python code):
#define N 10
void diag_step(int[][] matrix) {
for (int i = 0; i < N; i++) {
int j = 0;
int k = i;
printf("starting a strip\n");
while (j < N && i >= 0) {
printf("%d ", matrix[j][k]);
k--;
j++;
}
printf("\n");
}
for (int i = 1; i < N; i++) {
int j = N-1;
int k = i;
printf("starting a strip\n");
while (j >= 0 && k < N) {
printf("%d ", matrix[k][j]);
k++;
j--;
}
printf("\n");
}
}
Я думал, что у этой проблемы есть тривиальное решение, пара циклов for и несколько причудливых счетчиков
Точно.
Важно отметить, что если вы дадите каждому элементу индекс ( i , j ) то элементы на той же диагонали имеют одинаковое значение j + n - i , где n - ширина вашей матрицы. Поэтому, если вы выполняете итерацию по матрице обычным способом (т.е. вложенные циклы по i и j ), вы можете отслеживать диагонали в массиве, который рассматривается в вышеупомянутом путь.
// Этот алгоритм работает для матриц всех размеров. ;)
int x = 0;
int y = 0;
int sub_x;
int sub_y;
while (true) {
sub_x = x;
sub_y = y;
while (sub_x >= 0 && sub_y < y_axis.size()) {
this.print(sub_x, sub_y);
sub_x--;
sub_y++;
}
if (x < x_axis.size() - 1) {
x++;
} else if (y < y_axis.size() - 1) {
y++;
} else {
break;
}
}