编程珠玑: 12章 取样问题 12.1程序的输入包含两个整数m和n,其中m<n。输出是0~n-1范围内m个随机整数的有序列表,不允许重复-------解题总结
2017-01-25 09:22
423 查看
#include <iostream> #include <stdio.h> #include <vector> #include <algorithm> using namespace std; /* 问题:程序的输入包含两个整数m和n,其中m<n。输出是0~n-1范围内m个随机整数的有序列表,不允许重复。从概率的角度说,我们希望得到没有重复的有序选择,其中 每个选择出现的概率相等。 分析:这个感觉是蓄水池抽样问题。先设置0~m-1为前m个随机整数,然后对于i从m开始,生成随机数k,如果k < m - 1,就将i和k进行调换。 下面证明该程序的等概率:假设从1~n个数中随机选择m个不同的数,且概率相等。 假设当前为第i+1个数,则第i+1个数出现在蓄水池的概率为m/(i+1),现在证明前面i个数中出现在蓄水池的概率也为m(i+1)【先以简单的部分作为论点,论述 前面较难的条件成立】 证明:前面i个数出现蓄水池的概率=第i+1次选择前出现在蓄水池的概率 * 第i+1次选择不被替换的概率 = m/i * (1 - 第i+1次选择被替换的概率) = m/i * (1 - 1/(i+1) = m/(i+1) 关键: 1 证明前面i个数出现在蓄水池的概率和第i+1个数出现在蓄水池的概率相同 2 蓄水池步骤:1 将原数组A[1...m]赋值给新数组B[1...m],对于x属于m+1~n,随机得到一个数k,若k <= m ,就交换B[x]和B[k] 输入: 10(随机选择的数) 100(整数范围n) 输出: 10个不同元素组成的有序列表 */ int randRange(int min , int max) { if(min > max) { int temp = min; min = max; max = temp; } return ( rand() % (max - min + 1) + min ); } //生成0~n-1中m个随机选择的不重复的数组成的有序列表 vector<int> getRandomVector(int m , int n) { vector<int> results; //前面m个数的直接拷贝 for(int i = 0 ; i < m ; i++) { results.push_back(i); } //后面的随机替换 for(int i = m ; i < n ; i++) { int k = randRange(0 , n - 1); if(k <= m - 1) { results.at(k) = i; } } //替换后的结果注意要排序 sort(results.begin() , results.end()); return results; } void print(vector<int>& results) { if(results.empty()) { cout << "no result" << endl; return; } int size = results.size(); for(int i = 0 ; i < size; i++) { cout << results.at(i) << " "; } cout << endl; } void process() { int m , n; vector<int> results; while(cin >> m >> n) { results = getRandomVector(m , n); print(results); } } int main(int argc , char* argv[]) { process(); getchar(); return 0; }
相关文章推荐
- 编程珠玑: 12章 取样问题 12.1程序的输入包含两个整数m和n,其中m<n。输出是0~n-1范围内m个随机整数的有序列表,不允许重复。 优化解法-------解题总结
- 编程珠玑: 12章 取样问题 12.3设计空间,程序的输入包含两个整数m和n,其中m<n。输出是0~n-1范围内m个随机整数的有序列表,不允许重复。 -------解题总结
- 编程珠玑: 12章 取样问题 12.3设计空间,程序的输入包含两个整数m和n,其中m<n。输出是0~n-1范围内m个随机整数的有序列表,不允许重复。 解法2-------解题总结
- 编程珠玑: 13章 搜索 13.2使用链表结构,生成[0 ,maxval]范围内m各随机整数的有序序列 -------解题总结
- 编程珠玑: 13章 搜索 13.2使用线性结构,生成[0 ,maxval]范围内m各随机整数的有序序列 -------解题总结
- Problem Description 有一个长度为n(n<=100)的数列,该数列定义为从2开始的递增有序偶数,现在要求你按照顺序每m个数求出一个平均值,如果最后不足m个,则以实际数量求平均值。编程输出该平均值序列。 Input 输入数据有多组,每组占一行,包含两个正整数n和m,n和m的含义
- ACM457现在给出了一个只包含大小写字母的字符串,不含空格和换行,要求把其中的大写换成小写,小写换成大写,然后输出互换后的字符串。输入 第一行只有一个整数m(m<=10),表示测试数据组数。
- 创建一个包含15个随机整数(0~9)的列表,然后去掉其中的所有重复数字。
- 编程珠玑: 13章 搜索 13.4使用整数结构,生成[0 ,maxval]范围内m各随机整数的有序序列 -------解题总结
- 编程珠玑: 13章 搜索 13.1生成[0 ,maxval]范围内m各随机整数的有序序列 -------解题总结
- 编写程序,生成一个包含20个随机整数的列表,然后对其中偶数下标的元素进行降序排列,基数下标的元素不变
- 查找程序中的错误(平凡的程序,不平凡的问题) 4.不定义第三个变量,互换两个变量的值 5.char 类型转换 6.输出 10~100 之间的随机整数
- /*编写程序,其中自定义一函数,用来判断一个整数是否为素数,主函数输入一个数,输出是否为素数*/
- 输入两个整数n和m, 从数列1,2,...,n中任意选择几个数,使其和等于m, 要求编写程序输出所有的组合
- 输入一个整数,如果该整数大于1000,则输出“big”,如果该整数介于100到1000之间(包含两个边界),则输出“middle”,如果上面两种情况都不满足,输出”small“
- 编一个程序,输入10个整数,并放在数组中,先降序输出所有的数,再统计并输出其中正数、负数和零的个数
- 1.编写一个简单的C语言程序:根据输入的两个整数求平均值并且在终端输出,通过gcc编译器得到它的汇编程序文件。 2.编写一个C语言程序:打印输出所有“水仙花数”,用gdb调试程序(给出步骤)。所谓“
- 4.输入一个整数,如果该整数大于1000,则输出“big”,如果该整数介于100到1000之间(包含两个边界),则输出“middle”,如果上面两种情况都不满足,输出”small“
- 假设有两个包含整数的vector对象,编写一段程序,检验其中一个vector对象是否是另一个的前缀。
- Java猜数游戏:编写一个猜数程序,该程序随机在1到1000的范围中选择一个供用户猜测的整数。界面上提供一个文本框来接收用户输入的猜测的数,如果用户猜得太大,则背景变为红色,如果猜得太小,背景变为蓝色