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

    本程序实现从文件中随即选取一行,每行被选中的概率与改行长度成正比。
    程序用一次遍历,实现带权随机选取。
    算法:假设第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
    ",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);
      }
    }
    



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

  • 相关阅读:
    poj 2674 Linear world
    poj 3185 The Water Bowls
    The Largest Clique (uva11324)
    Proving Equivalences (LA 4287)
    强联通分量( HihoCoder 1185 )
    求点双联通分量(HihoCoder
    求桥,割点(HihoCoder
    欧拉回路
    uva10054
    表达式树(公共表达式消除 uva 12219)
  • 原文地址:https://www.cnblogs.com/luo-peng/p/4646260.html
Copyright © 2011-2022 走看看