编程珠玑:取样问题
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、 实现一种解决方案。用简单的代码和最有效的操作来实现最终选取的解决方案。
方法一:依次考虑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、 实现一种解决方案。用简单的代码和最有效的操作来实现最终选取的解决方案。
相关文章推荐
- 编程珠玑(2)第十二章学习笔记 取样问题
- 取样问题(编程珠玑)
- 编程珠玑(三)取样问题
- 编程珠玑:取样问题
- 取样问题——《编程珠玑》读书笔记
- 《编程珠玑》阅读小记(9) — 取样问题
- 《编程珠玑》--读书笔记12章:取样问题
- 编程珠玑第十二章--应用之取样问题
- 编程珠玑 12 取样问题
- 取样问题——《编程珠玑》学习笔记
- 编程珠玑--第12章 取样问题
- 编程珠玑之取样问题
- 编程珠玑: 12章 取样问题 12.1程序的输入包含两个整数m和n,其中m<n。输出是0~n-1范围内m个随机整数的有序列表,不允许重复-------解题总结
- 编程珠玑第12章(取样问题)学习笔记
- 《编程珠玑》阅读小记(9) — 取样问题
- 编程珠玑 3.7.4 日期问题
- 第12章 取样问题
- 编程珠玑第一章,电话号码排序问题
- 【编程珠玑】第十二章 取样问题
- 位图法;海量数据处理之位图技巧;位图技巧;海量数据;编程珠玑第二章问题A;40亿整数;腾讯面试题