檔案中隨機讀取行問題
1. 有一個檔案,如何在不知道有多少行的情況下讀取該檔案,從中隨機選擇並輸出一行
當我們讀取第 i (i > 0) 行時,以 1 / i 的概率選擇第
i 行,並替換掉原來選的行。
即總選擇第一行,並以概率 1 / 2 選擇第 2 行,以概率 1 / 3 選擇第
3 行,依次類推。
到檔案結束時,每個行被選中的概率都相等。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#define MAX_LINE_LEN 4096
int main()
{
srand(time(NULL));
const char *filename = "input.txt";
FILE * file = fopen(filename, "r");
char line_buffer[MAX_LINE_LEN];
char selection[MAX_LINE_LEN];
int i = 1;
while(fgets(line_buffer, MAX_LINE_LEN, file))
{
if(rand()%i == 0)
strcpy(selection, line_buffer);
++i;
}
puts(selection);
fclose(file);
return 0;
}
簡單推一下。到 1 行時,沒問題,跳過。
到第 2 行時,第 2 行被選中的概率是1 / 2,那第 1 行被選中的概率也是 1 / 2 。
到第 3 行時,第 3 行被選中的概率是 1 / 3,第 1 行和第 2 行被選中的概率是 (1 / 2) * (2 / 3),依次遞推。
到第 i 行時,第 1 ~ i 行每行被選中的概率都是 1 / i ,到檔案最後一行也是這樣。
2. 有一個檔案,如何在不知道有多少行的情況下讀取該檔案,從中隨機選擇並輸出k行(假設保證k小於檔案總行數)
先讀入第 1 ~ k 行儲存,以後每次讀入第 i 行,都以 k / i 的概率把剛讀入的一行隨機替換之前儲存的 k 行中的一行。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#define MAX_LINE_LEN 4096
int main()
{
int k = 5;
srand(time(NULL));
char line_buffer[MAX_LINE_LEN];
char **selections = (char **)malloc(k*sizeof(char*));
for(int i = 0; i < k; ++i)
selections[i] = (char *)malloc(MAX_LINE_LEN*sizeof(char));
const char *filename = "input.txt";
FILE * file = fopen(filename, "r");
// 先讀取 1 ~ k 行
for(int i = 0; i < k; ++i)
fgets(selections[i], MAX_LINE_LEN, file);
int i = k+1;
while(fgets(line_buffer, MAX_LINE_LEN, file))
{
if(rand()%i < k)
{
// 隨機替換已有的某一行
int j = rand()%k;
strcpy(selections[j], line_buffer);
}
++i;
}
for(int i = 0; i < k; ++i)
puts(selections[i]);
fclose(file);
for(int i = 0; i < k; ++i)
free(selections[i]);
free(selections);
return 0;
}
簡單推一下。設 1 ~ i ( i >= k ) 行每行被選中的概率都為 k / i ,當我們讀取第 i + 1 行時,以 k / (i+1) 的概率保留該行,並隨機替換已儲存的某一行(已儲存的每行被替換掉的概率是 1 / k )。這樣,第 i + 1 行被選取的概率是 k / (i + 1) ,其他行被選取的概率為
(k / i ) * (1 - k / ( i + 1 ) ) + ( k / i) * (k / ( i + 1 )) * ( 1 - 1 / k ),
前面的是第 i + 1 行不被保留時的情況,後面的是第 i+1 行保留並把該行替換掉的情況,最終結果也是 k / ( i + 1 ),所以到第 i + 1 行為止,每行被選取的概率仍然都相同。到檔案結尾同樣滿足。
相關文章
- 【Django】檔案讀取時路徑問題Django
- Perl IO:隨機讀寫檔案隨機
- 如何使用Python讀取文字檔案並回答問題?Python
- go學習之檔案讀取問題(需更新)Go
- java中讀取配置檔案Java
- Java 專案讀取 resource 資原始檔路徑問題Java
- JavaWeb中讀取【專案路徑下檔案】的路徑問題:this.getServletContext().getRealPath()JavaWebServletContext
- Golang專案中讀取配置檔案Golang
- 關於dataWithContentsOfFile 讀取大檔案的記憶體問題記憶體
- kodbox讀取alist檔案失敗,問題解決過程
- os.Open 讀取檔案和 vim 編輯的問題
- 讀取檔案最後一行
- SpringBoot 解決打包釋出後讀取不到 json 檔案問題Spring BootJSON
- 如何在python中讀取配置檔案Python
- 任意檔案讀取
- Java 讀取檔案Java
- 深入理解 Laravel 中.env 檔案讀取Laravel
- Java中的獲取檔案的物理絕對路徑,和讀取檔案Java
- python讀取檔案指定行的三種方法Python
- windows powershell 如何讀取大檔案前10行Windows
- springboot 執行 jar 包讀取外部配置檔案Spring BootJAR
- 檔案快取是不是有問題啊快取
- 檔案隨機或順序讀寫原理深入淺出隨機
- go配置檔案讀取Go
- python讀取大檔案Python
- springboot讀取配置檔案Spring Boot
- 用友任意檔案讀取
- viper 讀取配置檔案
- matlab讀取npy檔案Matlab
- python小白檔案讀取Python
- cocos讀取plist檔案
- python 讀取文字檔案Python
- IOC - 讀取配置檔案
- 前端讀取excel檔案前端Excel
- [java IO流]之 隨機訪問檔案(RandomAccessFile類)Java隨機randomMac
- 讀取resources中properties檔案內容範例
- Maui 讀取外部檔案顯示到Blazor中UIBlazor
- 如何在Shell指令碼中逐行讀取檔案指令碼
- python中xlrd庫如何實現檔案讀取?Python