编程珠玑笔记第12章习题

1 ,rand的返回值最大值是7fff

 使用位操作产生大的随机值

 

View Code
int bigRand()
{
    return rand()<<15&rand();
}
int rand(int l,int u)
{
    int k=(rand()%3)<<30&(rand()<<15)&rand();
    return l+k%(u-l+1);
}

2,随机选取0-n之间的一个i,取i,i+m-1共m个数,结果取模

3,m<n/2时,从n取一个数,在集合中的概率小于1/2,因此取值次数的期望是2

  这里题目的描述并不严谨

4,总共要取m次,集合的大小从0,1,2...m-1,次数的期望分别是n/n,n/(n-1),n/(n-2)...n/(n-m+1)

  当m=n时,和大概是nln(n)

7,第一问:添加一个最大值,输出时用最大值减一下,ps,如果m很大肯定会栈溢出

View Code
void randselect(int m,int n,int nMax)
{
    if(m>0)
    {
        if(rand()%n<m)
        {
            printf("%d\n",nMax-n+1);
            randselect(m-1,n-1,nMax);
        }else
        randselect(m,n-1,nMax);
         
    }
}

 第二问:每一个元素要么选要么不选,递归产生所有的情况

View Code
void randselect(int m,int n,vector<int> p)
{
    if(m>0)
    {
        if(n>m)
            randselect(m,n-1,p);
        p.push_back(n-1);
        randselect(m-1,n-1,p);         
         
    }else
    {
        for (int i=0;i<p.size();i++)
        {
            printf("%d ",p[i]);
        }
        printf("\n");
    }
}
int main()
{
    vector<int> t;
    randselect(2,10,t);
    system("pause");
    return 1;
}

8,产生有顺序的数,然后混合一下,书后答案是生成后就输出,这个答案比较靠谱..

   基于集合的算法可以使用比如multiset保存数

   直接生成m个数

9,使用Floyd的生成算法

  可以证明每个元素被选到的概率相等

10,这个题目是看明白了,答案看不明白,谷歌一下终于明白了

  答案的意思是说不断读取下一行,同时保存一个变量x指示当前应选择的行

  在第n行时有1/n的概率将x设为n

  可以用递归证明取每一行的概率都是1/n

11,其实就是3在12后面的概率,因为不用考虑其他元素,这个概率是1/3

12,话说我没找到它说的那个m=0就会崩溃的程序,知道作者指的是哪个程序,我觉的作者的意思是某个历史上的程序如何如何,我觉得这里翻译得不大好,有些歧义

   测试方法:可以生成大量数据进行统计

     

  

   

原文地址:https://www.cnblogs.com/mightofcode/p/2765439.html