您的位置:首页 > 编程语言

编程珠玑:取样问题

2014-06-17 14:48 239 查看
本章问题:取样问题,主要讲述一个从0~n-1范围内选择m个随机数(有序的)

方法一:依次考虑0,1,…,n-1之间的每个整数,并通过一个适当的随机测试对每个整数进行选择,一般来说,要从r个剩余的整数中选择s个,那么选择下一个整数的概率为s/r。

//在0~n-1范围内按序随机选择m个整数

RadnomSelect(m,n):

 select=m

 remaining=n

  fori=[0,n)

    if (bigrand()%remaining)<select //bigrand()返回一个较大的随机数

           print i

           select--

        remaining—

该方法的时间复杂度为O(n)。

方法二:在一个初始为空的集合(不含重复元素)中插入随机整数,直到个数足够。

        while size<m do

       t=bigrand()%n

              ift is not in S

                 insert t into S

                 size++

        print the elements of S in sorted order

这里的数据结构S要求可以保证整数有序,不存在重复元素。可以利用C++标准模板库中set表示集合,set底层采用红黑树实现,是一种较平衡的二叉查找树。用C++语言编写的函数如下:

        void gensets(int m,int n)

        {

               set<int> S;

               while(S.size()<m)

               {

                      s.insert(bigrand()%n);

               }

               set<int>::iterator it;

               for(it=S.begin();it!=S.end();++it)

                      cout<<*it<<'\n';

        }

方法三:

把0~n-1范围内的整型数组顺序打乱,然后把前m个整数排序输出。

改进:只需打乱数组的前m个元素,然后将前m个整数排序输出。C++代码如下:

void genshuf(int m,int n)

        {

               int i,j;

               int *x=new int
;

               for(i=0;i<n;++i)

                      x[i]=i;

               for(i=0;i<m;++i)

               {

                      j=randint(i,n-1);//生成i~n-1范围内的一个随机数

                      intt=x[i];

                      x[i]=x[j];

                      x[j]=t];

               }

 

               sort(x,x+m);

               for(i=0;i<m;++i)

                      cout<<x[i]<<"\n";

        }

 

 

编程过程的几个重要步骤:

1、 正确理解所遇到的问题。

2、 提炼出抽象的问题。简洁、明确的问题陈述不仅可以帮助我们解决当前遇到的问题,还有助于我们把解决方案应用到其他问题中。

3、 考虑尽可能多的解法。多思考一些可能的解决方案,寻找较优的方法,不仅可以提升程序的效率,还可能会缩短编写代码的时间。

4、 实现一种解决方案。用简单的代码和最有效的操作来实现最终选取的解决方案。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  编程珠玑