わかりました、最初の発言で申し訳ありませんが、最初の回答へのコメントで説明したように機能させたい場合は、実際にはデータを再ソートする必要があります...まあまあ。ヘルパー マトリックスがなくても実行できるかもしれませんが、結果のコードは非常に複雑になる可能性があり、マトリックスが数バイトのメモリしか使用しない限り、この小さなヘルパー コンストラクトを使用しないのはなぜでしょうか?
以下の私のコードは、マトリックスを作成しています。行列を上から下に書き、次に左から右に書きます (そして、最初の行のすべての列を埋める要素がなくなると、最初の行以外は埋めなくなります)。次に、左から右、上から下の別の順序で読みます。基本的にここで行っているのは行列の転置です、ある順序で書き、別の順序で読むことによって。行列の転置は非常に初歩的な数学的操作です (多くの 3D プログラミングは行列計算を使用して動作しますが、転置は実際には単純な操作です)。秘訣は、最初にマトリックスを埋める方法です。どのような場合でも最初の列を埋めることができるようにするために、必要な列の数と配列のサイズに関係なく、要素を使い果たした場合は通常の順序で行列を埋めるのをやめ、残りのすべての要素を最初の行。これにより、コメントで提案した出力が生成されます。
正直なところ、全体は少し複雑ですが、その背後にある理論は正気であり、うまく機能するはずです:-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 などに簡単に移植できる必要があります。大きな魔法は必要ないため、ほぼ普遍的で、移植可能で、クロスプラットフォームです。
追加する必要がある1つの重要なこと:
このコードは、Columns を 0 に設定するとクラッシュします (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 要素があるとうまくいきますが、その場合、結果の出力に穴はありません。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