编程珠玑之取样问题
来源:互联网 发布:mac笔记本右键怎么按 编辑:程序博客网 时间:2024/04/29 07:33
要从0~n-1的整数中取出来m(m<n)个整数。
有几种算法,第一种算法是严格按照概率得到,满足每个数取得的概率相同。原理和抓阄时候一样,先取和后取得并没有概率上的差别,第一个数字0取得的概率为m/n,当rand()%n<m的时候取得0。以后要调整m和n的值,才可以使得取得的概率相同,这种方法容易理解,并且严格满足m/n的条件。
第二种算法和以前一篇的洗盘算法比较相似,但是并不是严格的每个数字取到的概率为m/n,算法是这样的,先生成一个n维的整数数组,a值为0~n-1,然后生成m个n内的随机整数rand,然后交换a[i]和a[rand](i=0...m-1)。至于是否是满足m/n证明好像有点难。
第三种算法更加直接,用一个set容器存放产生的随机整数,一直产生n内的随机整数填入容器,一直到set的size为m的时候即可。
对于三种算法,如果要求产生的整数为有序的,那么第二第三中算法还有排序,第一种算法是自然有序的,但是当n较大的时候,第一种算法运行的时间可能比较长。对于第一种算法,当n较大,m较小的时候,可以判断下m是否为0,如果为零可以跳出循环。还有别的情况,如果n和m都很大,而且m很接近n的时候,那么可以产生n-m个n内的随机整数,然后输出没有产生的随机整数。还有当n为2的32次方,m为1000万的时候,这种情况,可以直接生成1100万个随机的整数,然后去除重复的整数得到1000w个随机整数。注意RAND_MAX可能小于2的32次方,这时候就要对rand()函数进行改写,假设RAND_MAX为2的31次方,那么可以写个bigRand(){return rand()+rand()};
- #include <iostream>
- #include <set>
- using namespace std;
- //rand()函数生成一个0到RAND_MAX(stdlib.h中定义的值为2147483647(有符号整数的最大值))之间的整数
- void rand_select1(int n, int m);//在0~n内选择出m个整数
- void rand_select2(int n, int m);
- void rand_select3(int n, int m);
- void exchange(int *a, int i, int j);
- int main()
- {
- //rand_select1(30, 2);
- //rand_select2(30, 2);
- rand_select3(30, 2);
- return 0;
- }
- void rand_select1(int n, int m)
- {
- srand(time(0));
- for(int i=0; i<n; i++)
- {
- if(rand()%(n-i) < m)
- {
- printf("%d\n", i);
- m--;
- }
- }
- }
- void rand_select2(int n, int m)
- {
- srand(time(0));
- int *a = new int[n];
- for(int i=0; i<n; i++)
- a[i] = i;
- for(int i=0; i<m; i++)
- exchange(a, i, rand()%n);
- for(int i=0; i<m; i++)
- printf("%d\n", a[i]);
- }
- void rand_select3(int n, int m)
- {
- srand(time(0));
- set<int> S;
- while(S.size()<m)
- S.insert(rand()%n);
- set<int>::iterator i;
- for(i=S.begin(); i!=S.end(); ++i)
- printf("%d\n", *i);
- }
- void exchange(int *a, int i, int j)
- {
- int temp = a[i];
- a[i] = a[j];
- a[j] = temp;
- }
- 编程珠玑之取样问题
- 编程珠玑:取样问题
- 编程珠玑 12 取样问题
- 编程珠玑 12 取样问题
- 编程珠玑第十二章--应用之取样问题
- 《编程珠玑》--读书笔记12章:取样问题
- 【编程珠玑】第十二章 取样问题
- 编程珠玑(三)取样问题
- 编程珠玑--第12章 取样问题
- 《编程珠玑》第12章:取样问题
- 12、编程珠玑笔记十二取样问题
- 编程珠玑第12章(取样问题)学习笔记
- 编程珠玑(2)第十二章学习笔记 取样问题
- 《编程珠玑》阅读小记(9) — 取样问题
- 取样问题——《编程珠玑》学习笔记
- [编程珠玑笔记]第12章 取样问题
- 取样问题 总数n事先不知道,等概率取样 (编程珠玑chapter12 课后题10)
- 随机取样(《编程珠玑》第12章)
- 排序(一)冒泡排序
- RDLC报表设置横向打印
- 转载的InnoDB常见参数及其设置值
- IOS之UIWebView的使用---转载之红黑联盟
- IOS 网络初探(一) - NSURLConnection
- 编程珠玑之取样问题
- Cookie在Get请求和Post请求中的区别
- 学习Wireshark(三):应用Wireshark IO图形工具分析数据流
- android 中的IPC方式
- The Swift Programming Language中文/英文版
- 007-httpd-2.2拾遗
- CocoaPods报错:The dependency `` is not used in any concrete target
- HBase修改Table压缩格式步骤
- Log4j2介绍和特性实例(六)--配置文件不在默认路径下的加载