如何在C语言中实现0、1均匀分布的二维随机数组?
实现C语言二维数组中0和1数量各占一半的方案
如果需要严格保证二维数组里0和1的数量各占一半,而不是仅概率上的近似均匀,直接用rand()%2随机生成的方式无法满足——因为它只能保证概率接近50%,但无法确保最终数量完全对等。下面提供两种可靠的实现方案:
方案一:预填充+随机洗牌(推荐)
这个方法逻辑简单且高效,先固定0和1的数量,再通过洗牌打乱顺序,确保分布随机且数量严格各半。以6×6数组为例,总共有36个元素,我们需要18个0和18个1:
完整代码示例
#include <stdio.h> #include <stdlib.h> #include <time.h> #define ROWS 6 #define COLS 6 int main() { int arr[ROWS][COLS]; int total = ROWS * COLS; int half = total / 2; // 1. 初始化数组:前half个元素为1,剩余为0 for (int i = 0; i < ROWS; i++) { for (int j = 0; j < COLS; j++) { int idx = i * COLS + j; arr[i][j] = (idx < half) ? 1 : 0; } } // 2. 使用Fisher-Yates洗牌算法打乱数组 srand(time(NULL)); for (int i = total - 1; i > 0; i--) { // 生成0到i之间的随机索引 int j = rand() % (i + 1); // 转换为二维数组的行列坐标 int row_i = i / COLS; int col_i = i % COLS; int row_j = j / COLS; int col_j = j % COLS; // 交换元素 int temp = arr[row_i][col_i]; arr[row_i][col_i] = arr[row_j][col_j]; arr[row_j][col_j] = temp; } // 3. 输出数组 for (int i = 0; i < ROWS; i++) { for (int j = 0; j < COLS; j++) { printf("%d", arr[i][j]); } printf("\n"); } return 0; }
代码说明
- 初始化阶段:通过一维索引的方式,先给前半部分元素赋值1,后半部分赋值0,确保数量严格各半。
- 洗牌阶段:Fisher-Yates算法是一种无偏的洗牌方法,能保证每个元素出现在任意位置的概率均等,最终数组的0和1分布完全随机。
方案二:动态生成+补全
如果不想预先填充数组,可以先生成随机值,同时统计0和1的数量,当其中一种数量达到一半时,剩余位置直接填充另一种值:
代码示例
#include <stdio.h> #include <stdlib.h> #include <time.h> #define ROWS 6 #define COLS 6 int main() { int arr[ROWS][COLS]; int total = ROWS * COLS; int half = total / 2; int count_1 = 0; int count_0 = 0; srand(time(NULL)); for (int i = 0; i < ROWS; i++) { for (int j = 0; j < COLS; j++) { if (count_1 == half) { arr[i][j] = 0; count_0++; } else if (count_0 == half) { arr[i][j] = 1; count_1++; } else { int val = rand() % 2; arr[i][j] = val; val ? count_1++ : count_0++; } } } // 输出数组 for (int i = 0; i < ROWS; i++) { for (int j = 0; j < COLS; j++) { printf("%d", arr[i][j]); } printf("\n"); } return 0; }
代码说明
- 每次生成随机值前,先检查0或1的数量是否已经达到一半,若达到则直接填充另一种值,确保最终数量严格对等。
- 这种方法的随机性略逊于洗牌方案(因为后面的元素是固定填充),但实现起来也比较简单。
补充说明
原代码中rand()%2的问题:rand()的返回范围是0到RAND_MAX,如果RAND_MAX是奇数(比如常见的32767),那么rand()%2得到0的概率会比1略高一点,虽然差异极小,但无法保证数量严格各半。因此如果需要精确的数量对等,必须使用上述两种方案。
内容的提问来源于stack exchange,提问作者nicou000
相关产品推荐
相关产品推荐

