Матрица пересечения в Диагональных полосах

Для быстрой и грязной фиксации иногда я просто прокручиваю вверх и вниз, и выделение приспосабливается. Ctrl + L для экранной перерисовки может также зафиксировать его.

31
задан alyx 22 November 2009 в 16:41
поделиться

8 ответов

Вот кое-что, что вы можете использовать. Просто замените 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
62
ответ дан 27 November 2019 в 21:23
поделиться

вам нужно разбить матрицу на верхнюю и нижнюю части и перебирать каждую из них отдельно, сначала одну половину строки, сначала другой столбец. предположим, что матрица 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) ...
0
ответ дан 27 November 2019 в 21:23
поделиться

Я бы, вероятно, сделал что-то вроде этого (заранее извиняюсь за любые ошибки индекса, не отлаживал это):

// 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);
}
0
ответ дан 27 November 2019 в 21:23
поделиться

Псевдокод:

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
ответ дан 27 November 2019 в 21:23
поделиться

Я бы сдвинул строки следующим образом:

1  2  3  x  x
x  4  5  6  x
x  x  7  8  9

И просто перебрал столбцы. На самом деле это можно сделать без физического переключения.

41
ответ дан 27 November 2019 в 21:23
поделиться

Ключ состоит в том, чтобы перебрать каждый элемент в первой строке и от нее идти вниз по диагонали. Затем повторите каждый элемент в последнем столбце (без первого, который мы прошли на предыдущем шаге), а затем спуститесь по его диагонали.

Вот исходный код, который предполагает, что матрица является квадратной матрицей (непроверенной, переведенной из рабочей 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");
    }   
}   
1
ответ дан 27 November 2019 в 21:23
поделиться

Я думал, что у этой проблемы есть тривиальное решение, пара циклов for и несколько причудливых счетчиков

Точно.

Важно отметить, что если вы дадите каждому элементу индекс ( i , j ) то элементы на той же диагонали имеют одинаковое значение j + n - i , где n - ширина вашей матрицы. Поэтому, если вы выполняете итерацию по матрице обычным способом (т.е. вложенные циклы по i и j ), вы можете отслеживать диагонали в массиве, который рассматривается в вышеупомянутом путь.

3
ответ дан 27 November 2019 в 21:23
поделиться

// Этот алгоритм работает для матриц всех размеров. ;)

    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;

        }

    }
2
ответ дан 27 November 2019 в 21:23
поделиться
Другие вопросы по тегам:

Похожие вопросы: