2017-02-23 133 views
2

Я распечатал массив 6x6 1d, но хочу повернуть против часовой стрелки в верхнюю левую часть 3x3. Есть ли алгоритм для этого? В будущем я также хочу повернуть, как нижняя правая секция 3x3 или верхняя правая секция 3x3 или нижняя левая секция 3x3.Как повернуть часть массива 1d в C?

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

3x3 - это нечто особенное, потому что средний вход не перемещается. Можете ли вы показать нам, что произойдет в случае 4x4? –

+1

Можете ли вы сделать это, если бы это была * только * верхняя левая матрица 3x3? Если нет, это может быть хорошим первым шагом, и лучший способ узнать, как это сделать, - это сделать это на бумаге. Когда вы его работаете над бумагами, у вас есть матрица 4x4 и сделайте «поворот» в верхней левой части 3x3 с этой маленькой матрицей. Когда вы можете сделать это с помощью матрицы 4x4, вы сможете применить ее к любой матрице MxN (где M> 3 и N> 3). Когда вы можете сделать это на бумаге, попробуйте уточнить алгоритм до простых небольших и дискретных шагов. И, наконец, переведите эти маленькие шаги в код. –

+0

Вы можете hald-вычислить массив из девяти различий между предварительно повернутыми и послевращенными индексами: 'diff [] = {0-1,1-2,2-8,6-0,7-7, .. .} '. Как только вы выберете, какой подмассив для вращения, получите массив индексов в этом подмассиве (например, 'ix [] = {' 8, '9,10,24,25,26,30,31,32}' для нижнего уровня, левый угол) и _somehow_ swap 'a [k]' с 'a [k + diff [k]]' для каждого 'k'. (Часть _somehow_ означает, что это просто сырая идея, а не решение). – DyZ

ответ

1

Здесь важно различать, как распределяются вещи в памяти и как вы их представляете. Нет такой вещи, как «массив 6x6 1D», потому что 1D-массивы не имеют строк и столбцов. Поэтому начните с преобразования этого 1D-массива в 2D-массив 6x6.

Затем вы можете определить центр вращения, указав координаты (x, y). Вы должны разумно проверить эти координаты, чтобы они не были на краях матрицы (альтернативно, спроектируйте алгоритм так, чтобы это было возможно, если это необходимо).


Тупой решением является просто захватить индексы вокруг центра и перемещать данные в жестко закодированы образом:

array[center_x-1][center_y-1] = array[center_x][center_y-1]; 
... 

и так далее. Это будет самый быстрый способ, и самое простое решение часто является лучшим.


Более модульный подход, который позволяет переменное направлению вращения было бы создать массив указателей, указывающие на данных вокруг центра, который должен быть повернут. Этот массив указателей может быть реализован в виде простой формы связанного списка:

typedef struct rotate_node_t rotate_node_t; 
typedef struct rotate_node_t 
{ 
    rotate_node_t* next; 
    rotate_node_t* prev; 
    int* data; 
} rotate_node_t; 

Вы бы иметь rotate_node_t rotation [8], которые могли бы его индексы назначенные как:

0 1 2 
7 c 3 
6 5 4 

где «с» центр.

С помощью этого на месте вы можете просто перебирать связанный список в любом направлении и перемещать данные с одного узла на другой. Он более гибкий, чем прямой доступ к массиву, но медленнее и сложнее. И его можно было бы расширить, чтобы поддерживать всевозможные дикие шаблоны вращения.