C#之桶中取黑白球问题
《编程之美》284页,问题4.6:桶中取黑白球。
有一个桶,里面有白球、黑球各100个,人们必须按照以下规则把球取出来:
1. 每次从桶中拿两个球;
2. 如果两球同色,再放入一个黑球;
3. 如果两球异色,再放入一个白球;
问:最后桶里面只剩下一个黑球的概率是多少?
于是我开始分析,桶里装球,每次摸球是随机的,所以不能用队列和栈,那就用万能的动态列表来做桶吧。按照题目描述的顺序,写出取球的过程,最后剩的是黑球返回1,白球返回2,其他情况(没球了)返回3,然后根据概率在大数据量下将会趋于稳定的性质无限取球,最后趋于稳定的那个数就是答案。
代码如下(注释的部分为调试程序过程中用到的测试代码,用来显示操作过程中取球、放球、以及桶中球的详细变化过程):
using System;
using System.Collections.Generic;
using System.Linq; namespace BucketBall
{
class Program
{
static void Main(string[] args)
{
int count = ;
int targetCount = ;
int result;
double probability;
while (true)
{
List<string> bucketBalls = new List<string>();
result = Play(bucketBalls);
//Console.WriteLine("result:" + result);
if (result == )
{
targetCount++;
//Console.WriteLine("targetCount:" + targetCount);
}
count++;
//Console.WriteLine("count:" + count);
probability = Math.Round((double)1.0 * targetCount / count, );
Console.WriteLine(probability);
//Console.Read();
}
}
private static int Play(List<string> bucketBalls)
{
for (int i = ; i <= ; i++)
{
bucketBalls.Add("BlackBall");
bucketBalls.Add("WhiteBall");
}
//PrintList(bucketBalls);
Random ran = new Random();
while (bucketBalls.Count() > )
{ var balls = Take(bucketBalls, , ran);
//Console.WriteLine("Take the balls " + balls[0] + " " + balls[1]);
//PrintList(bucketBalls);
if (balls[] == balls[])
{
Put(bucketBalls, "BlackBall");
//Console.WriteLine("Put the BlackBall");
//PrintList(bucketBalls);
}
else
{
Put(bucketBalls, "WhiteBall");
//Console.WriteLine("Put WhiteBall over!");
//PrintList(bucketBalls);
}
//Console.WriteLine(bucketBalls.Count());
}
if (bucketBalls.Count() == )
{
//Console.WriteLine("result is " + bucketBalls[0]);
return bucketBalls[] == "BlackBall" ? : ;
}
else
{
return ;
}
} private static void PrintList(List<string> bucketBalls)
{
Console.WriteLine();
foreach (var ball in bucketBalls)
{
Console.Write(ball + " ");
}
Console.WriteLine();
} private static void Put(List<string> bucketBalls, string v)
{
bucketBalls.Add(v);
} private static List<string> Take(List<string> bucketBalls, int v, Random ran)
{
List<string> balls = new List<string>();
int pos;
for (int i = ; i <= v; i++)
{
pos = ran.Next(, bucketBalls.Count());
balls.Add(bucketBalls[pos]);
bucketBalls.RemoveAt(pos);
}
return balls;
}
}
}
我因为不小心将一处的“WhiteBall”写成了“WhileBall”而一度修改却得不到正确的答案,最终一步一步的通过上面的测试代码,才将出错范围最终锁定在了初始化bucketBalls的for循环内,最终发现我将“WhiteBall”写成了“WhileBall”。改过来以后,运行结果终于正确了。下面是去掉测试代码的最终版:
using System;
using System.Collections.Generic;
using System.Linq; namespace BucketBall
{
class Program
{
static void Main(string[] args)
{
int count = ;
int targetCount = ;
int result;
double probability;
while (true)
{
List<string> bucketBalls = new List<string>();
result = Play(bucketBalls);
if (result == )
{
targetCount++;
}
count++;
probability = Math.Round((double)1.0 * targetCount / count, );
Console.WriteLine(probability);
}
}
private static int Play(List<string> bucketBalls)
{
for (int i = ; i <= ; i++)
{
bucketBalls.Add("BlackBall");
bucketBalls.Add("WhiteBall");
}
Random ran = new Random();
while (bucketBalls.Count() > )
{ var balls = Take(bucketBalls, , ran);
if (balls[] == balls[])
{
Put(bucketBalls, "BlackBall");
}
else
{
Put(bucketBalls, "WhiteBall");
}
}
if (bucketBalls.Count() == )
{
return bucketBalls[] == "BlackBall" ? : ;
}
else
{
return ;
}
} private static void Put(List<string> bucketBalls, string v)
{
bucketBalls.Add(v);
} private static List<string> Take(List<string> bucketBalls, int v, Random ran)
{
List<string> balls = new List<string>();
int pos;
for (int i = ; i <= v; i++)
{
pos = ran.Next(, bucketBalls.Count());
balls.Add(bucketBalls[pos]);
bucketBalls.RemoveAt(pos);
}
return balls;
}
}
}
通过运行结果可以看出来,概率一直很稳定,为1:

所以答案是在白球和黑球各100个的前提下取球放球,最后都只剩下黑球,概率为1。
修改程序中的初始化参数还可以用来求解课后题中的拓展情况,不用动脑。大家可以试试。
总结过程中遇到的问题:
1、字符串赋值的时候一定要仔细,别写错了!
2、Random.Next()函数返回值的范围包括 minValue 但不包括 maxValue。如果 minValue 等于 maxValue,则返回 minValue。
C#之桶中取黑白球问题的更多相关文章
- 今盒子里有n个小球,A、B两人轮流从盒中取球,每个人都可以看到另一个人取了多少个
/* 题目描述 今盒子里有n个小球,A.B两人轮流从盒中取球,每个人都可以看到另一个人取了多少个,也可以看到盒中还剩下多少个,并且两人都很聪明,不会做出错误的判断. 我们约定: 每个人从盒子中取出的球 ...
- 压缩感知中的lp球:p范数最优化为什么总会导致一个稀疏的解的原因
转自:彬彬有礼. 压缩感知中的lp球:p范数最优化为什么总会导致一个稀疏的解的原因 http://blog.csdn.net/jbb0523/article/details/40268943 题目: ...
- 定时从远程的数据库中取数据,然后把取出来的数据插入或更新本地的oracle数据库的表
最近项目中有一种需求: 大致需求是这样的 通过给定的 用户名和密码 要定时从远程的数据库中取数据,然后把取出来的数据插入或更新本地的oracle数据库的表 项目的结构式struts1 hibernat ...
- LoadRunner中取Request、Response
LoadRunner中取Request.Response LoadRunner两个“内置变量”: 1.REQUEST,用于提取完整的请求头信息. 2.RESPONSE,用于提取完整的响应头信息. 响应 ...
- DataGrid中取HyperLinkColumn列的值,处理DataGrid中绑定的特殊字符
DataGrid中取HyperLinkColumn列的值. /// <summary> /// 对datagrid中标签进行编码,处理特殊字符 /// </summary> / ...
- 【算法与数据结构】在n个数中取第k大的数(基础篇)
(转载请注明出处:http://blog.csdn.net/buptgshengod) 题目介绍 在n个数中取第k大的数(基础篇),之所以叫基础篇是因为还有很多更高级的算法,这些 ...
- Java中取小数点后两位(四种方法)
摘自http://irobot.iteye.com/blog/285537 Java中取小数点后两位(四种方法) 一 Long是长整型,怎么有小数,是double吧 java.text.D ...
- 使用回溯法求所有从n个元素中取m个元素的组合
不多说了,直接上代码,代码中有注释,应该不难看懂. #include <stdlib.h> #include <stdio.h> typedef char ELE_TYPE; ...
- 总结C++中取成员函数地址的几种方法
这里, 我整理了4种C++中取成员函数地址的方法, 第1,2,4种整理于网上的方法, 第3种cdecl_cast是我自己想到的. 其中, 第4种(汇编)的方法不能在VC6上编译通过. 推荐使用第1,2 ...
随机推荐
- Codeforce Round #222 Div2
这场断网,本来有个别人的比较卡的无线 但后面睡着了- -! C:额,逆向想下! B:... A:...
- 认识javascript
javascript小知识 www.phonegap.com(跨平台开发框架) Cocos2d-Html5(WebGL渲染 javascript语言) creatjs.com(融合了flash动画的 ...
- 3D语音天气球(源码分享)——创建可旋转的3D球
开篇废话: 在9月份时参加了一个网站的比赛,比赛的题目是需要使用第三方平台提供的服务做出创意的作品. 于是我选择使用语音服务,天气服务,Unity3D,Android来制作一个3D语音天气预报,我给它 ...
- ie6双边距解决
这个bug是ie6有名的双边距bug:同时为一个元素设置向一个方向偏移和对这个方向进行外边距设置,比如float:left,margin-left:45px;在其他浏览器下是显示正常的,在ie6下这个 ...
- full_case & parallel_case
case中的full_case与parallel_case讨论: 1)术语介绍: 整个case模块叫做:case_statement,注释部分叫做case_statement_header case ...
- TP主从服务器配置
在config.php文件中,设置‘DB_DEPLOY_TYPE’=>1,‘DB_HOST’=>‘localhost,192.168.0.1,192.168.0.23’,各个主机之间用逗号 ...
- 重要的事情说三遍:列表 ul / ol 等是块级元素,是块级元素,块级元素
HTML 块级元素 大多数 HTML 元素被定义为块级元素或内联元素. 编者注:“块级元素”译为 block level element,“行内元素”译为 inline element. 块级元素在浏 ...
- js之arguments对象的使用
- C++11—lambda函数
[1]lambda表达式语法定义 lambda表达式的语法定义如下: [capture] (parameters) mutable ->return-type {statement}; (1) ...
- sql创建删除修改表的基本操作
1 建立表格 在建立好数据库以后,就可以根据储存资料的需求,使用SQL叙述建立所有需要的表格(table).建立表格的设定非常多,以建立"world.city"表格来说,它的叙述会 ...