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

C语言如何从存储文件内容的数组中等概率抽取不重复行

C语言实现从plates.txt读取行后无重复等概率随机选取

原有代码问题修正

你当前的代码存在核心逻辑错误:char line[100]是栈上的共享缓冲区,所有string[i] = line赋值都让指针指向同一块内存,最终数组所有元素都会指向最后一行的内容,无法实现多行存储,需要为每一行单独分配内存存储内容。

实现思路

要满足所有行被选中概率相等、每行仅被选中一次的要求,我们使用Fisher-Yates洗牌算法实现,该算法时间复杂度为O(n),可以保证元素打乱后每个位置的取值概率完全相等,按打乱后的顺序取行即可满足需求,具体步骤:

  1. 正确读取文件所有行,每行单独分配内存存入指针数组
  2. 初始化随机数种子
  3. 使用Fisher-Yates算法打乱指针数组顺序
  4. 按打乱后的顺序依次取行输出,天然无重复且概率均等

完整可运行代码

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

int main(void) {
    int line_count = 0;
    char* string[100];
    char line[100];
    FILE *file; 
    
    // 打开文件
    file = fopen("plates.txt", "r"); 
    if (file == NULL) {
        perror("打开文件失败");
        return 1;
    }

    // 读取所有行,单独分配内存存储
    while(fgets(line, sizeof line, file) != NULL && line_count < 100) {
        // 去掉fgets读取到的换行符(可选,根据需求调整)
        line[strcspn(line, "\n")] = '\0';
        // 为当前行分配内存并拷贝内容
        string[line_count] = malloc(strlen(line) + 1);
        strcpy(string[line_count], line);
        line_count++;
    }
    fclose(file);

    if (line_count == 0) {
        printf("文件为空\n");
        return 0;
    }

    // 初始化随机数种子,仅需执行一次
    srand((unsigned int)time(NULL));

    // Fisher-Yates 洗牌算法打乱数组
    for (int i = line_count - 1; i > 0; i--) {
        // 生成0到i之间的随机索引
        int j = rand() % (i + 1);
        // 交换元素
        char* temp = string[i];
        string[i] = string[j];
        string[j] = temp;
    }

    // 示例:依次输出所有随机不重复的行,需要取多少就取前多少个
    printf("随机选取的行:\n");
    for (int i = 0; i < line_count; i++) {
        printf("%s\n", string[i]);
        // 用完释放内存,避免泄漏
        free(string[i]);
    }

    return 0;
}

可选实现:不打乱原数组的方案

如果你需要保留原数组的顺序,可以额外维护一个访问标记数组,每次生成随机索引直到找到未访问过的行:

// 初始化访问标记数组
int visited[100] = {0};
int pick_count = 3; // 假设要选3行
for (int i = 0; i < pick_count; i++) {
    int rand_idx;
    do {
        rand_idx = rand() % line_count;
    } while (visited[rand_idx]);
    visited[rand_idx] = 1;
    printf("第%d次选中:%s\n", i+1, string[rand_idx]);
}
// 最后记得释放string数组的内存

内容的提问来源于stack exchange,提问作者user17276226

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 04:36:04