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)
全栈程序员-站长的头像全栈程序员-站长

相关推荐

  • 搓牙机调试位置讲解_hadoopjps进程不全

    搓牙机调试位置讲解_hadoopjps进程不全1、strace-p[进程号]strace-p1002297strace:Process1002297attachedfutex(0x7fcbb95f3f84,FUTEX_WAIT_PRIVATE,1,NULL可以看到死在了futex(0x7fcbb95f3f84,FUTEX_WAIT_PRIVATE,1,NULL

    2022年9月14日
  • JAVA为啥要用stream流处理_java哪个部分最难学

    JAVA为啥要用stream流处理_java哪个部分最难学小应学长带你学Java

    2022年10月6日
  • pycharm-professional-2022.01.13 激活码(注册激活)

    (pycharm-professional-2022.01.13 激活码)2021最新分享一个能用的的激活码出来,希望能帮到需要激活的朋友。目前这个是能用的,但是用的人多了之后也会失效,会不定时更新的,大家持续关注此网站~https://javaforall.net/100143.htmlIntelliJ2021最新激活注册码,破解教程可免费永久激活,亲测有效,上面是详细链接哦~0V…

    2022年3月31日
  • Java中Ajax学习「建议收藏」

    Java中Ajax学习「建议收藏」1.Ajax:异步js和xml异步刷新:如果网页中某一个地方需要修改,异步刷新可以使,只刷新该需要修改的地方,而页面其他中的地方保持不变。例如:百度搜索框,视频的点赞等实现(两种方式):Js:XMLHttpRequest对象XMLHttpRequest对象的方法:open(方法名【提交方式get或者post】,服务器地址,ture【是否选用异步刷新,99%都是ture】):与服务端建立连接send():get: send(null)post: send(参数值)setRequestHe

    2022年7月7日
  • gridbaglayout布局_gridsearch

    gridbaglayout布局_gridsearch自己想做个小程序,却在布局上犯了难,使用FlowLayout和BorderLayout这些功能不够强大,使用GridBagLayout却不会,只好求助于文档了。文档对这个布局管理器介绍很详细,但是最痛苦的是英文。不过幸好它有实例,经过在网上查阅和推敲实例,终于对GridBagLayout的使用有了一个成型的了解,拿出来与大家分享。GridBagLayout是一个灵活的布局管理器,部件如果想

    2022年9月9日
  • python读取txt文件中的json数据

    python读取txt文件中的json数据txt文本文件能存储各式各样数据,结构化的二维表、半结构化的json,非结构化的纯文本。存储在excel、csv文件中的二维表,都是可以直接存储在txt文件中的。半结构化的json也可以存储在txt文本文件中。最常见的是txt文件中存储一群非结构化的数据:今天只学习:从txt中读出json类型的半结构化数据importpandasaspdimportjsonf=o…

    2022年5月18日

发表回复

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

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