随机带权选取文件中一行 分类: linux c/c++ 2014-06-02 00:11 344人阅读 评论(0) 收藏

时间:2023-11-22 17:10:50

本程序实现从文件中随即选取一行,每行被选中的概率与改行长度成正比。

程序用一次遍历,实现带权随机选取。

算法:假设第i行权重wi(i=1...n).读取到文件第i行时,以概率wi/(w1+w2+...+wi)

用该行替换上一轮被选中的行,直至读取文件结束。这样可以从数学上保证i行

被选中的概率为wi/(w1+w2+...+wn);

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<time.h>
#include <limits.h>
#define BUFSIZE 4096
char selected[BUFSIZE];
void randselect(FILE*fp);
void main(int argc,char* argv[])
{
srand(time(NULL));
FILE *fp;
if(argc!=1&&argc!=2)
{
fprintf(stderr,"Invalid argument number.");
exit(1);
}
if(argc==1)
fp=stdin;
else
{
if(NULL==(fp=fopen(argv[1],"r")))
{
fprintf(stderr,"cann't open %s\n",argv[1]);
exit(2);
}
}
randselect(fp);
printf("%s",selected);
fclose(fp);
exit(0);
} void randselect(FILE*fp)
{
char *line=NULL;
size_t size = 0;
long int len,sumlen=0;
while((len=getline(&line,&size,fp))!=-1)
{
long int prelen=sumlen;
sumlen+=len;
long int tmp=(long int)((double)rand() / RAND_MAX *LONG_MAX) ;//扩大随机数的范围
tmp%=sumlen;
if(tmp>=prelen) //以[prelen,sumlen-1]/[0,sumlen-1]的概率换入该行
strcpy(selected,line);
}
}

版权声明:本文为博主原创文章,未经博主允许不得转载。