`

从n个对象中随机取出m个

 
阅读更多

很多类似的这种问题,都有两种方案,一种以时间换空间,一种以空间换时间。

 对于方法一:这里可以计算一下其每次循环的概率是否都相同,

假设i=0,随机到元素的概率为m/n;

假设i=1,随机到元素的概率为m/n*((m-1)/(n-1))+(1-m/n)*(m/(n-1))=m/n(分别假设i=0时没有随机到和有随机到)

...

所以每次循环所随机到元素的概率都相同。

//此方法摘录于其他网站,是一种省空间省时间的方案。注意,这里返回数值是坐标,即n=3,m=1,则返回值为0~2的一个数
	public static Integer[] way1(int n, int m) {
		Integer[] output = new Integer[m];
		for (int i = 0; i < n; i++) {
			// if (m > 0 && new Random().nextInt(n - i) % (n - i) < m) {//这个也可以
			if (m > 0 && random(1, n-i) % (n - i) < m) {
				int index = output.length - m;
				output[index] = i;
				m--;
			}
		}
		return output;
	}

	public static List<String> way1(List<String> names, int m) {
		List<String> output = new ArrayList<>(m);
		int n = names.size();
		for (int i = 0; i < n; i++) {
			if (m > 0 && random(1, n - i) % (n - i) < m) {
				output.add(names.get(i));
				m--;
			}
		}
		return output;
	}

	public static final int random(int begin, int end) {
		if (begin > end) {
			throw new RuntimeException("随机开始值大于结束值");
		}

		if (begin == end) {
			return begin;
		}

		int dec = begin - 0;
		Random r = new Random();
		// nextInt(n)随机的结果为0~n-1,所以加1效果是end这个值也可以随机到
		int random = r.nextInt(end - dec + 1);// 保证开始值为0,且结束值>0,即begin-dec=0
		return random + dec;
	}

	//线程安全的随机类
	public static final int random2(int begin, int end){
		if (begin > end) {
			throw new RuntimeException("随机开始值大于结束值");
		}

		if (begin == end) {
			return begin;
		}
		return ThreadLocalRandom.current().nextInt(begin, end+1);
	}

	// 此方法以空间换时间,只需循环n次即可
	public static int[] way2(int n, int m){
		int[] sequence = new int[n];
        int[] output = new int[m];
        Random r = new Random();
        for (int i = 0; i < n; i++)
        {
            sequence[i] = i;
        }

        int end = n - 1;
        for (int i = 0; i < m; i++)
        {
            int num = r.nextInt(n);
            output[i] = sequence[num];
            sequence[num] = sequence[end];
            end--;
        }
        return output;
	}

 

另外,摘录了几个算法题,总觉得答案需要仔细琢磨一下,仅供参考:

题目2

假设你参加了一个游戏节目,现在要从三个密封的箱子中选择一个。其中两个箱子是空的,另一个箱子里面有大奖。你并不知道奖在哪一个箱子里,但主持人知道。游戏节目的主持人先要你选择一个箱子,接着他把你没有选的空箱子打开,以证明它是空的。最后主持人给你换箱子的机会,你可以把你所选择的箱子换成另一个没有打开的箱子。此时你该不该换箱子?

 

分析:

要相信直觉。你当然应该换箱子!我们把三个箱子编号A,B,C,并假设你选的是A箱。显然奖品在A里的概率是1/3,在B或C里的概率是2/3。B和C可能有一个是空的,也可能两个都是空的。因此,当你选择了A箱后,主持人很可能会打开B箱或C箱,以显示里面是空的。在这种情况下,主持人的举动并不会影响奖品在A箱里面的机会。我们假设主持人打开了B箱,以告诉你它是空的。现在A箱有奖品的概率还是1/3,B箱里面有奖品的概率是0,因此C箱里面有奖品的概率是2/3。在这种情况下,你应该换到C箱,因为它使你赢的机会提高了1倍!

 

题目3

有一对夫妇,先后生了两个孩子,其中一个孩子是女孩,问另一个孩子是男孩的概率是多大?

 

答案是2/3.两个孩子的性别有以下四种可能:(男男)(男女)(女男)(女女),其中一个是女孩,就排除了(男男),还剩三种情况。其中另一个是男孩的占了两种,2/3. 之所以答案不是1/2是因为女孩到底是第一个生的还是第二个生的是不确定的。

分享到:
评论

相关推荐

    2004~2015年程序员软考考试上午真题合集.pdf

    在数组和矩阵中,一维数组T[0...m*n-1]可以通过每隔n个元素取出一个元素依次存入数组B[1...m]中。 * question 14: A.T[(k-1)*n] B.T[k*n] C.T[(k-1)*m] D.T[k*m] 回答:A.T[(k-1)*n] 7.递归函数 在递归函数...

    dbscan算法实验报告.pdf

    6)在当前簇核心对象队列Ωcur中取出一个核心对象o′,通过邻域距离阈值ε找到所有的ε-邻域子样本集Nε(o′),令Δ =Nε(o′) ∩Γ,更新当前簇样本集合Ck=Ck∪Δ,更新未访问样本集合Γ =Γ -Δ,更新Ωcur=Ωcur...

    《你必须知道的495个C语言问题》

    *2.5 在C语言中是否有模拟继承等面向对象程序设计特性的好方法? 22 2.6 为什么声明extern f(struct x *p); 给我报了一个晦涩难懂的警告信息? 23 2.7 我遇到这样声明结构的代码:struct name {int namelen; ...

    你必须知道的495个C语言问题

    *2.5 在C语言中是否有模拟继承等面向对象程序设计特性的好方法? 2.6 为什么声明externf(structx*p);给我报了一个晦涩难懂的警告信息? 2.7 我遇到这样声明结构的代码:structname{intnamelen;charnamestr[1];}...

    语言程序设计课后习题答案

    从一般意义上讲,对象是现实世界中一个实际存在的事物,它可以是有形的,也可以是无形的。对象是构成世界的一个独立单位,它具有自己的静态特征和动态特征。面向对象方法中的对象,是系统中用来描述客观事物的一个...

    会计理论考试题

    23.如果要把C盘某个文件夹中的一些文件复制到C盘的另外一个文件央中,在选定文件后,若采用拖放操作,可以用___B___目标的方法。 A、直接拖至 B、Ctrl十拖至 C、Alt十拖至 D、单击 24.Windows98中的磁盘的根文件夹是...

    数据结构(C++)有关练习题

    就在第n行之前插入后续文本,如果I后面没有跟数字,就在当前行之前插入文本,如果输入D,后面跟着m,n,一个数字n或者没有数字,就分别删除m到n行,第n行或者当前行,命令L用于显示文本; 6、 用C++编写求多项式...

    LINGO软件的学习

    LINGO是用来求解线性和非线性优化问题的简易工具。LINGO内置了一种建立最优化模型的语言,可以简便地表达大规模问题,利用LINGO高效的求解器可快速求解并分析结果。...一个对象列中至多有一个集名,而属性...

    c# 加密和解密相关代码

    在第一个GroupBox 中放入3 个TextBox 控件和一个Button 按钮,分别用于输入数字、输入加密数字、显示加 密后的数字和计算加密信息;在第二个GroupBox 中放入一个TextBox 控件和一个Button 按钮,分别用于显示 解密后...

    用c描述的数据结构演示软件

    右侧上方为算法文本,在算法中有4个形式参量,其中值参 n 为圆盘个数,x、y、和 z 分别表示3个塔座;右侧下方为递归工作栈,栈中每个记录包含调用语句行号 adr 及值参 n 和 x、y、z;左侧上方显示汉诺塔图形及移动...

    数据结构演示软件

    右侧上方为算法文本,在算法中有4个形式参量,其中值参 n 为圆盘个数,x、y、和 z 分别表示3个塔座;右侧下方为递归工作栈,栈中每个记录包含调用语句行号 adr 及值参 n 和 x、y、z;左侧上方显示汉诺塔图形及移动...

    (重要)AIX command 使用总结.txt

    P -&gt;列出预定义设备对象类中设备的有关信息,即支持的设备,缺省显示信息包括class,type,subclass,description r ColumnName -&gt;指定列名 S State -&gt;列出指定状态的设备,3种状态可选,(1)已定义-&gt;defined,d,D,0;(2)...

Global site tag (gtag.js) - Google Analytics