编程珠玑--第12章 取样问题
来源:互联网 发布:mysql中删除列 编辑:程序博客网 时间:2024/05/14 13:03
问题描述:程序的输入包含两个整数m和n,其中m<n。输出是0~n-1范围内m个随机整数的有序列表,不允许重复。从概率的角度说,我们希望得到没有重复的有序序列,其中每个选择出现的概率相等。
讨论这些问题前有两个假设:1.有一个函数bigrand()能够返回很大的随机整数(远远大于m和n)。
2.另一个函数randint(i,j)能够返回i..j范围内均匀选择的随机整数。
解法一:假设m=2,n=5,选择第一个数0的概率为2/5,可以通过以下语句来实现:if(bigrand()%5)<2,<2也就是只能取0或者1,表示了概率为2/5。但是当我们选择1的时候,要根据前面是否选择了0。如果选择了0,则按照1/4的概率选择1,而未选择0的情况下按照2/4的概率选择1,以此类推。当m=n的时候,一定能够被选中(因为bigrand()%m<n(m)一定是成立的)。
select=mremaining=nfor i=[0,n)if(bigrand()%remaining)<selectprint iselect--remaining--分析:这里我们是遍历[0,n),然后用概率选择,如果选中了select和remaining都要减1,如果没有选中remaining减1。当select减少到0的时候程序虽然在运行,但是已经不可能再选中了,所以可以修改一下程序当select减少为0的时候跳出。Knuth给出了证明,每个子集被选中的可能性是相等的。
c++实现:
void getknuth(int m,int n){for(int i=0;i<n;i++)if((bigrand()%(n-i))<m){cout<<i<<"\n";m--;}}
解法二:在一个初始为空的集合里面插入随机整数,直到个数足够。我们这里使用c++ stl中的set来实现。
set是一个容器,它其中包含的元素值是唯一的。比如我们以下面这段程序说明:
#include<iostream>#include<set>using namespace std;int main(){set<int> s;s.insert(3);s.insert(3);cout<<s.size();return 0;}输出的值是1,若相同的话set选择不插入。
void getsets(int m,int n){set<int> S;while(S.size()<m)S.insert(bigrand()%n);set<int>::iterator i;for(i=S.begin();i!=S.end();++i)cout<<*i<<endl;}解法三:把包含0~n-1的数组顺序打乱,然后把前m个元素排序输出。
void genshuf(int m,int n){int i,j;int *x=new int[n];for(i=0;i<n;i++)x[i]=i;for(i=0;i<m;i++){j=randint(i,n-1);int t=x[i];x[i]=x[j];x[j]=t;}sort(x,x+m);for(i=0;i<m;i++)cout<<x[i]<<endl;}
- 编程珠玑--第12章 取样问题
- 《编程珠玑》第12章:取样问题
- 编程珠玑第12章(取样问题)学习笔记
- [编程珠玑笔记]第12章 取样问题
- 随机取样(《编程珠玑》第12章)
- 《编程珠玑》--读书笔记12章:取样问题
- 编程珠玑 12 取样问题
- 编程珠玑 12 取样问题
- 编程珠玑:取样问题
- 12、编程珠玑笔记十二取样问题
- 【编程珠玑】第十二章 取样问题
- 编程珠玑之取样问题
- 编程珠玑(2)第十二章学习笔记 取样问题
- 编程珠玑第十二章--应用之取样问题
- 编程珠玑(三)取样问题
- 第12章 取样问题
- 《编程珠玑》阅读小记(9) — 取样问题
- 取样问题——《编程珠玑》学习笔记
- 一篇精彩的ABAP日记(转载)
- git 提交修改
- HDOJ 2553 N皇后问题
- oracle regular expression (正则表)
- GLSL 高级教程 – Rasterization and Interpolation
- 编程珠玑--第12章 取样问题
- 学习的困惑
- OpenGL ES之glOrtho和glFrustum的区别
- __u64等的格式化输出
- Android如何获取Root权限
- Android中不被硬件加速支持的操作
- SPFA: Power Transmission
- hdu2363
- flash 满窗口播放