大小为n的拉丁方阵是指各行列中的每个符号仅出现一次,随机拉丁方阵生成任意给定n个符号的随机输出。
以n=4为例生成随机拉丁方阵
0 2 3 1
2 1 0 3
3 0 1 2
1 3 2 0
任务
创建一个给定大小为n的生成随机拉丁方阵的函数(routine/procedure/method/… ),并使用该函数生成一个n=5的随机拉丁方阵。
代码实现
C
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
// low <= num < high
int randInt(int low, int high) {
return (rand() % (high - low)) + low;
}
// shuffle an array of n elements
void shuffle(int *const array, const int n) {
if (n > 1) {
int i;
for (i = 0; i < n - 1; i++) {
int j = randInt(i, n);
int t = array[i];
array[i] = array[j];
array[j] = t;
}
}
}
// print an n * n array
void printSquare(const int *const latin, const int n) {
int i, j;
for (i = 0; i < n; i++) {
printf("[");
for (j = 0; j < n; j++) {
if (j > 0) {
printf(", ");
}
printf("%d", latin[i * n + j]);
}
printf("]\n");
}
printf("\n");
}
void latinSquare(const int n) {
int *latin, *used;
int i, j, k;
if (n <= 0) {
printf("[]\n");
return;
}
// allocate
latin = (int *)malloc(n * n * sizeof(int));
if (!latin) {
printf("Failed to allocate memory.");
return;
}
// initialize
for (i = 0; i < n; i++) {
for (j = 0; j < n; j++) {
latin[i * n + j] = j;
}
}
// first row
shuffle(latin, n);
// middle row(s)
for (i = 1; i < n - 1; i++) {
bool shuffled = false;
while (!shuffled) {
shuffle(&latin[i * n], n);
for (k = 0; k < i; k++) {
for (j = 0; j < n; j++) {
if (latin[k * n + j] == latin[i * n + j]) {
goto shuffling;
}
}
}
shuffled = true;
shuffling: {
}
}
}
//last row
used = (int *)malloc(n * sizeof(int));
for (j = 0; j < n; j++) {
memset(used, 0, n * sizeof(int));
for (i = 0; i < n - 1; i++) {
used[latin[i * n + j]] = 1;
}
for (k = 0; k < n; k++) {
if (used[k] == 0) {
latin[(n - 1) * n + j]