C#之桶中取黑白球问题

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 = 0;
            int targetCount = 0;
            int result;
            double probability;
            while (true)
            {
                List<string> bucketBalls = new List<string>();
                result = Play(bucketBalls);
                //Console.WriteLine("result:" + result);
                if (result == 1)
                {
                    targetCount++;
                    //Console.WriteLine("targetCount:" + targetCount);
                }
                count++;
                //Console.WriteLine("count:" + count);
                probability = Math.Round((double)1.0 * targetCount / count, 2);
                Console.WriteLine(probability);
                //Console.Read();
            }
        }
private static int Play(List<string> bucketBalls) { for (int i = 1; i <= 2; i++) { bucketBalls.Add("BlackBall"); bucketBalls.Add("WhiteBall"); } //PrintList(bucketBalls); Random ran = new Random(); while (bucketBalls.Count() > 1) { var balls = Take(bucketBalls, 2, ran); //Console.WriteLine("Take the balls " + balls[0] + " " + balls[1]); //PrintList(bucketBalls); if (balls[0] == balls[1]) { 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() == 1) { //Console.WriteLine("result is " + bucketBalls[0]); return bucketBalls[0] == "BlackBall" ? 1 : 2; } else { return 0; } } 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 = 1; i <= v; i++) { pos = ran.Next(0, 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 = 0;
            int targetCount = 0;
            int result;
            double probability;
            while (true)
            {
                List<string> bucketBalls = new List<string>();
                result = Play(bucketBalls);
                if (result == 1)
                {
                    targetCount++;
                }
                count++;
                probability = Math.Round((double)1.0 * targetCount / count, 2);
                Console.WriteLine(probability);
            }
        }
private static int Play(List<string> bucketBalls) { for (int i = 1; i <= 100; i++) { bucketBalls.Add("BlackBall"); bucketBalls.Add("WhiteBall"); } Random ran = new Random(); while (bucketBalls.Count() > 1) { var balls = Take(bucketBalls, 2, ran); if (balls[0] == balls[1]) { Put(bucketBalls, "BlackBall"); } else { Put(bucketBalls, "WhiteBall"); } } if (bucketBalls.Count() == 1) { return bucketBalls[0] == "BlackBall" ? 1 : 2; } else { return 0; } }

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 = 1; i <= v; i++) { pos = ran.Next(0, bucketBalls.Count()); balls.Add(bucketBalls[pos]); bucketBalls.RemoveAt(pos); } return balls; } } }

通过运行结果可以看出来,概率一直很稳定,为1:

C#之桶中取黑白球问题

所以答案是在白球和黑球各100个的前提下取球放球,最后都只剩下黑球,概率为1。

修改程序中的初始化参数还可以用来求解课后题中的拓展情况,不用动脑。大家可以试试。

总结过程中遇到的问题:

1、字符串赋值的时候一定要仔细,别写错了!

2、Random.Next()函数返回值的范围包括 minValue 但不包括 maxValue如果 minValue 等于 maxValue,则返回 minValue

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/109241.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 作业2 分析TGA文件「建议收藏」

    一、TGA文件格式解析二、文件格式文件头(TgaFileHeader):由图像描述信息字段长度、颜色表类型、图像类型、颜色表说明和图像说明五个字段组成,总计18字节,描述了图像存储的基本信息,应用程序可依据该部分字段值读写图像数据。图像/颜色表数据(Image/ColorMapData):由图像描述信息(可选)、颜色表数据和图像数据三部分组成,用于存储图片的图像信息。开发者自定义区域(DeveloperArea):包含开发者定义字段列表和开发者字典(用于存储开发者定义字段的值),该区域为

    2022年4月9日
    41
  • eclipse安装android_安卓studio怎么打包apk

    eclipse安装android_安卓studio怎么打包apkEclipseandroid开发更改apk名字有以下几步:第一步,修改工程包名在eclipse里,找到项目包和java包(原则上都一样),就可以按”F2″修改名字,随之,源.java也会得到相应的修改;然而每个.java文件都需要把如下图内容,再额外修改一下第二步,修改AndroidManifest.xml文件AndroidManifest.xml里的内容是android工程的相关配置文件。工程文件的解析具体可参考:某鸟教程.第三步,修改Strings.xml文件然后是…

    2022年10月5日
    4
  • oracle级plsql安装教程,PLSQL 数据下载库安装使用教程,步骤解析

    oracle级plsql安装教程,PLSQL 数据下载库安装使用教程,步骤解析安装Oracle数据库一、首先安装Oracle数据库*64。二、下载并安装安装PLSQLDeveloper根据计算机的系统位数,从下载的安装包中选择合适的程序,双击“运行”以打开下一个PLSQL软件安装向导。四、根据协议,选中“我接受…”选项,然后单击以下内容。五、选择默认情况下安装在C盘目录中的安装位置,单击“更改”按钮自定义软件安装路径,确认后单击“下一步”。选择安装方式,标准(程序设置…

    2022年6月22日
    31
  • html 转换成 markdown,将HTML转换为Markdown

    html 转换成 markdown,将HTML转换为Markdown我在这个博客上最大的一个错误就是没有找到一个WordPress插件可以让我用markdown来写我的文章;直到今天,我仍然需要在“视觉”模式下写文章,然后手动将文章转换为“文本”模式的HTML。有一天,我想转换现有的帖子Markdown,然后启用一个插件,将Markdown转换为HTML。这个痛苦的过程让我问自己:有没有一种方法我可以使用Node.jsJavaScript转换HTML到Markd…

    2022年7月17日
    17
  • keyboard free download_Row five

    keyboard free download_Row five题目描述:Givenabinarytree,determineifitisheight-balanced.Forthisproblem,aheight-balancedb

    2022年8月4日
    8
  • python学习——pandas查看数据集null值:isnull

    python学习——pandas查看数据集null值:isnull在数据集中,可能有些字段下会有null值,我们在进行数据处理的时候,不能视而不见,可以使用isnull查看是否有空值In:all_dummy_df.isnull().sum().sort_values(ascending=False).head(10)Out:LotFrontage486GarageYrBlt159MasVnrArea23…

    2022年10月20日
    3

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号