需要生成一個包含 0 到 23 的隨機排列,即長度為 24 的數組,每個數字恰好出現一次,順序隨機。
初始化數組 a[i] = i,然後從最後一個元素向前,每次隨機選擇一個未處理的位置交換。
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define N 24
void shuffle(int *arr, int n) {
for (int i = n - 1; i > 0; i--) {
int j = rand() % (i + 1); // 0 ~ i
int tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
}
int main() {
srand((unsigned)time(NULL)); // 只調用一次!
int a[N];
for (int i = 0; i < N; i++) a[i] = i;
shuffle(a, N);
for (int i = 0; i < N; i++) {
printf("%d ", a[i]);
}
printf("\n");
return 0;
}
若需高質量隨機(如密碼學),可使用 /dev/urandom (Linux) 或 CryptGenRandom (Windows),或 C++11 的 std::mt19937。
生成不重複隨機數組的標準解法是 Fisher-Yates 洗牌。避免在循環中重複播種,避免朴素去重法。上述代碼簡潔、高效、正確。