檔案中隨機讀取行問題
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:隨機讀寫檔案隨機
- java 讀取.txt檔案時,注意的問題Java
- Java讀取文字檔案中文亂碼問題Java
- perl例子--讀取大檔案中某幾行
- go學習之檔案讀取問題(需更新)Go
- java中讀取配置檔案Java
- Golang專案中讀取配置檔案Golang
- Java 專案讀取 resource 資原始檔路徑問題Java
- 如何使用Python讀取文字檔案並回答問題?Python
- java RandomAccessFile類(隨機訪問檔案)JavarandomMac隨機
- java中讀取.properties配置檔案Java
- os.Open 讀取檔案和 vim 編輯的問題
- 關於websphere讀取war配置檔案出錯的問題Web
- 讀取檔案最後一行
- 動態引入js檔案使用隨機數防止讀取快取資料程式碼例項JS隨機快取
- JavaWeb中讀取【專案路徑下檔案】的路徑問題:this.getServletContext().getRealPath()JavaWebServletContext
- 關於dataWithContentsOfFile 讀取大檔案的記憶體問題記憶體
- kodbox讀取alist檔案失敗,問題解決過程
- Java 讀取檔案Java
- tiff檔案讀取
- 深入理解 Laravel 中.env 檔案讀取Laravel
- 如何在python中讀取配置檔案Python
- ArcEngine中載入和讀取Style檔案
- 文摘:在EJB中讀取XML配置檔案XML
- 簡單讀取XML檔案中的值XML
- 檔案隨機或順序讀寫原理深入淺出隨機
- Java中如何使用隨機存取檔案RandomAcessFile類?Java隨機randomMac
- 表中隨機取資料隨機
- Java中的獲取檔案的物理絕對路徑,和讀取檔案Java
- 從ARM機上讀取JPG檔案程式碼
- [java IO流]之 隨機訪問檔案(RandomAccessFile類)Java隨機randomMac
- Java讀取本地檔案,並顯示在JSP檔案中JavaJS
- python讀取檔案——python讀取和儲存mat檔案Python
- Homestead 執行配置快取後模版檔案找不到問題。快取
- viper 讀取配置檔案
- go配置檔案讀取Go
- iOS讀取.csv檔案iOS