Хорошо, я прошу прощения за мое первоначальное утверждение, но когда вы хотите, чтобы оно работало так, как вы описали в комментарии к моему первому ответу, вам нужно на самом деле пересортировать данные ... ну, в некоторой степени. Возможно, это можно сделать без вспомогательной матрицы, однако полученный код, вероятно, будет очень сложным, и пока матрица будет использовать только пару байтов памяти, почему бы не использовать эту маленькую вспомогательную конструкцию?
То, что мой код делает ниже, - это создание матрицы. Мы записываем матрицу сверху вниз, а затем слева направо (и прекращаем заполнять все, кроме первой строки, когда у нас заканчиваются элементы, чтобы заполнить все столбцы первой строки). Затем мы читаем это в другом порядке, слева направо и сверху вниз. По сути, мы делаем транспонирования матрицы , записывая ее в одном порядке, но читая ее в другом порядке. Транспонирование матрицы - это очень элементарная математическая операция (многие трехмерные программы работают с использованием матричных вычислений, а транспонирование на самом деле простая операция). Хитрость в том, как мы изначально заполняем матрицу. Чтобы убедиться, что мы можем заполнить первый столбец в любом случае, независимо от количества желаемых столбцов и размера массива, мы должны прекратить заполнять матрицу в нормальном порядке, если у нас заканчиваются элементы и резервируются все оставшиеся элементы для Первый ряд. Это приведет к выводу, который вы предложили в своем комментарии.
Если честно, все немного сложно, но теория, стоящая за этим, должна быть вменяемой, и она прекрасно работает: -D
int Columns;
char * Array[] = {"A", "B", "C", "D", "E", "F", "G"};
int main (
int argc,
char ** argv
) {
// Lets thest this with all Column sizes from 1 to 7
for (Columns = 1; Columns <= 7; Columns++) {
printf("Output when Columns is set to %d\n", Columns);
// This is hacky C for quickly get the number of entries
// in a static array, where size is known at compile time
int arraySize = sizeof(Array) / sizeof(Array[0]);
// How many rows we will have
int rows = arraySize / Columns;
// Below code is the same as (arraySize % Columns != 0), but
// it's almost always faster
if (Columns * rows != arraySize) {
// We might have lost one row by implicit rounding
// performed for integer division
rows++;
}
// Now we create a matrix large enough for rows * Columns
// references. Note that this array could be larger than arraySize!
char ** matrix = malloc(sizeof(char *) * rows * Columns);
// Something you only need in C, C# and Java do this automatically:
// Set all elements in the matrix to NULL(null) references
memset(matrix, 0, sizeof(char *) * rows * Columns );
// We fill up the matrix from top to bottom and then from
// left to right; the order how we fill it up is very important
int matrixX;
int matrixY;
int index = 0;
for (matrixX = 0; matrixX < Columns; matrixX++) {
for (matrixY = 0; matrixY < rows; matrixY++) {
// In case we just have enough elements left to only
// fill up the first row of the matrix and we are not
// in this first row, do nothing.
if (arraySize + matrixX + 1 - (index + Columns) == 0 &&
matrixY != 0) {
continue;
}
// We just copy the next element normally
matrix[matrixY + matrixX * rows] = Array[index];
index++;
//arraySize--;
}
}
// Print the matrix exactly like you'd expect a matrix to be
// printed to screen, that is from left to right and top to bottom;
// Note: That is not the order how we have written it,
// watch the order of the for-loops!
for (matrixY = 0; matrixY < rows; matrixY++) {
for (matrixX = 0; matrixX < Columns; matrixX++) {
// Skip over unset references
if (matrix[matrixY + matrixX * rows] == NULL)
continue;
printf("%s", matrix[matrixY + matrixX * rows]);
}
// Next row in output
printf("\n");
}
printf("\n");
// Free up unused memory
free(matrix);
}
return 0;
}
Вывод
Output when Columns is set to 1
A
B
C
D
E
F
G
Output when Columns is set to 2
AE
BF
CG
D
Output when Columns is set to 3
ADG
BE
CF
Output when Columns is set to 4
ACEG
BDF
Output when Columns is set to 5
ACEFG
BD
Output when Columns is set to 6
ACDEFG
B
Output when Columns is set to 7
ABCDEFG
Этот код на C должен легко портироваться на PHP, C #, Java и т. Д., В этом нет большой магии, поэтому он в значительной степени универсален, переносим и кроссплатформенен.
Одна важная вещь, которую я должен добавить:
Этот код завершится сбоем, если вы установите столбцы в ноль (деление на ноль, я не проверяю это), но какой смысл будет иметь значение 0 столбцов? И это также приведет к сбою, если у вас будет больше столбцов, чем элементов в массиве, я также не проверяю это. Вы можете легко проверить любой из них сразу после получения arraySize:
if (Columns <= 0) {
// Having no column make no sense, we need at least one!
Columns = 1;
} else if (Columns > arraySize) {
// We can't have more columns than elements in the array!
Columns = arraySize;
}
Кроме того, вы также должны проверить, что arraySize равен 0, и в этом случае вы можете сразу же выпрыгнуть из функции, так как в этом случае абсолютно ничего не нужно делать для функции :) Добавление этих проверок должно привести к потере кода твердое вещество. * * тысяча двадцать-одна
Работа с NULL Elements в массиве будет работать, кстати, в этом случае в результирующем выводе нет дыр. Элементы NULL просто пропускаются, как будто их нет. Например. давайте использовать
char * Array[] = {"A", "B", "C", "D", "E", NULL, "F", "G", "H", "I"};
Вывод будет
ADFI
BEG
CH
для столбцов == 4. Если вам нужны отверстия , вам нужно создать элемент отверстия.
char hole = 0;
char * Array[] = {"A", "B", &hole, "C", "D", "E", &hole, "F", "G", "H", "I"};
и немного изменить код рисования
for (matrixY = 0; matrixY < rows; matrixY++) {
for (matrixX = 0; matrixX < Columns; matrixX++) {
// Skip over unset references
if (matrix[matrixY + matrixX * rows] == NULL)
continue;
if (matrix[matrixY + matrixX * rows] == &hole) {
printf(" ");
} else {
printf("%s", matrix[matrixY + matrixX * rows]);
}
}
// Next row in output
printf("\n");
}
printf("\n");
Выходные образцы:
Output when Columns is set to 2
A
BF
G
CH
DI
E
Output when Columns is set to 3
ADG
BEH
I
CF
Output when Columns is set to 4
AC H
BDFI
EG