好的,我为我最初的陈述感到抱歉,但是当你想让它像你在我第一个答案的评论中所描述的那样工作时,你实际上需要对数据重新排序。。。嗯,有点。它可能不需要helper矩阵就可以完成,但是生成的代码可能非常复杂,只要矩阵只使用几个字节的内存,为什么不使用这个小helper构造呢?
transposing a matrix
,按一个顺序写,但按另一个顺序读。转置矩阵是一个非常基本的数学运算(许多3D编程都是通过使用矩阵计算进行的,转置实际上是一个简单的运算)。诀窍在于我们最初如何填充矩阵。为了确保在任何情况下都可以填充第一列,与所需列的数量和数组的大小无关,如果元素用完,必须停止按正常顺序填充矩阵,并保留第一行剩余的所有元素。这将产生您在评论中建议的输出。
老实说,整件事有点复杂,但背后的理论应该是理智的,而且工作起来很不错
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列有什么意义呢?如果数组中的列多于元素,它也会崩溃,我也不检查这一点。您可以在获得阵列大小后立即轻松检查:
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元素将有效,在这种情况下,结果输出中没有漏洞。空元素就像不存在一样被跳过。例如,让我们使用
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