C语言生成不重复随机数的两种常用方法

Miles
Miles
发布时间:2026-10-14| 6人浏览过
原创

在C语言开发中,生成唯一性随机数据(如抽奖、测试用例)是常见需求。本文将讲解如何利用标准库中的 srand 和 rand 函数,结合种子值与算法逻辑,实现1至N范围内不重复随机数的生成,涵盖基础原理及两种实用的代码实现方式。

理解C语言的随机数机制

C语言标准库提供的 rand() 函数并非真随机数,而是伪随机数,它依据一个内部的“种子”数值,通过递推公式计算出一系列看起来随机的数列。如果种子固定,生成的数列也将完全一致。

要实现真正的随机性,必须在调用 rand() 前使用 srand(unsigned int seed) 设置种子。通常采用当前时间作为种子,以确保程序每次运行时种子值不同:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main(void) {
    // 以当前时间为种子,保证每次运行结果不同
    srand((unsigned)time(NULL));
    
    // 生成0到RAND_MAX之间的随机整数
    int random_num = rand(); 
    return 0;
}

第1步:获取指定范围的随机数

直接使用 rand() 得到的范围过大且从0开始。若需要生成 X 到 Y 之间(包含X和Y)的随机数,可使用取模运算转换:

公式:k = rand() % (Y - X + 1) + X;

  • 目的:将巨大的随机范围压缩并平移至目标区间。
  • 操作:对 (Y-X+1) 取模得到 0 到 (Y-X) 的值,再加 X 偏移量。
  • 示例:生成 1-100 的随机数为 rand() % 100 + 1。

生成不重复随机数的核心难点

直接生成随机数并检查是否已存在,在数据量接近总数时效率极低(“猴子抛硬币”效应)。下面介绍两种高效或直观的实现思路。

方法一:标记数组法(适合小范围密集数据)

创建一个布尔型或整型数组作为“哈希表”,记录每个数字是否已被选中。循环直到凑齐所需数量,每生成一个数都检查标记。

  1. 准备数组:初始化一个大小为 N+1 的数组,全部置为0(表示未使用)。
  2. 生成与检查:生成目标范围内的随机数,若数组对应位置为0,则存入结果并标记为1;若为1,则重新生成。
  3. 终止条件:当收集的随机数达到预期数量时停止。

方法二:数组洗牌法(Fisher-Yates Shuffle,推荐)

此方法先生成一个包含所有可能值的有序数组,然后通过随机交换元素位置打乱顺序。取出前 N 个即为不重复随机序列,时间复杂度稳定为 O(N)。

复制代码 代码如下:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

// 交换两个整数的指针
void swap(int *pm, int *pn) {
    int temp = *pm;
    *pm = *pn;
    *pn = temp;
}

int main(void) {
    int a[513]; // 用于存储1-512
    int i;

    srand((unsigned)time(NULL));

    // 1. 初始化数组,填入顺序数值 1-512
    for(i = 1; i <= 512; i++) {
        a[i] = i;
    }

    // 2. 洗牌算法:从后往前,将当前位置与[1,当前位]之间的随机位置交换
    for(i = 512; i >= 1; i--) {
        // rand() % i + 1 生成 1 到 i 的随机索引
        swap(&a[i], &a[rand() % i + 1]);
    }

    // 3. 输出前10个作为不重复随机数示例
    for(i = 1; i <= 10; i++) {
        printf("%4d", a[i]);
    }
    printf("\n");

    return 0;
}

注意事项与排错

  • 头文件依赖:必须包含 <stdlib.h> 和 <time.h>。
  • 种子设置:如果在同一秒内多次快速调用程序,未使用 srand(time(NULL)) 可能导致相同的随机序列。
  • 非ANSI函数:避免使用 random() 等非标准函数,它在GCC等现代编译器中不可用,应统一使用 rand()。
  • 内存管理:对于极大的范围(如1-10000000),一次性创建数组可能消耗过多内存,此时可考虑使用位图或外部存储来辅助去重判断。

以上就是C语言生成不重复随机数的详细内容,更多关于C语言随机数算法的资料请关注本站其它相关文章!

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。