You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 12:45:47