C#上市Coin Toss可能性

时间:2017-05-21 07:59:48

标签: c#

大家好日子。我正在学习编程,并且我试图在一系列硬币投掷的所有可能结果中列出字符串列表,而下面的代码适用于少量硬币抛出(< 20,我出去了)内存异常),我想要一些可以处理更高数字(可能大约40)的东西。

我尝试用解决方案寻找类似的问题,但似乎没有什么能吸引我的眼球或我的水平。

任何人都可以告诉我,我做错了什么或者朝着正确的方向推动我吗?

public static class CoinToss {
    private const int numberTosses = 11;

    private static List<string> allPossibilities = new List<string>();

    public static void WriteAllPossibilities() {
        List<string> temp = new List<string>(); ;

        allPossibilities.Add("H");
        allPossibilities.Add("T");

        int tossIndex = 1;
        while (tossIndex++ < numberTosses) {
            /* Clear the temporary */
            temp.Clear();

            foreach (string outcome in allPossibilities) {
                temp.Add(outcome + "H");
                temp.Add(outcome + "T");
            }

            /* Remove all items in all possibilities */
            allPossibilities.Clear();

            /* Copy allPaths from temp */
            foreach (string path in temp) {
                allPossibilities.Add(path);
            }
        }

        foreach (string path in allPossibilities) {
            Console.WriteLine(path);
        }
        Console.WriteLine(allPossibilities.Count);

    }
}

1 个答案:

答案 0 :(得分:2)

令我感到惊讶的是,在所有&#34;硬币翻转&#34;中,并没有这个问题的例子。 Stack Overflow上已有问题。但是,我找不到合适的副本。您可能是第一个在硬币翻转的特定上下文中发布有关此特定问题的问题。

在评论中,you wrote

  

之后我需要处理列表,这就是为什么我要将它保存在列表中

这永远不会奏效。正如在评论中已经指出的那样,代表40个硬币翻转的所有可能组合将需要2 ^ 40个不同的序列。即使您保守并将它们一次存储在五个字节的打包数据结构中,仍然是5 ^字节内存的2 ^ 40倍,这几乎是5-1 / 2太字节。这在技术上是在64位进程的限制范围内,但在Windows或运行Windows的典型计算机将提供的范围内,不在任何合理的实际限制范围内。

此外,即使您可以存储所有这些序列,也需要花费大量时间对它们进行任何有用的操作。没有人能够快速阅读以查看整个列表;假设他们是超级快速读者,并且每秒可读取10次,那仍然是17,000年。

尽管如此,即使没有足够的时间来完成程序,生成它们的基本逻辑也很容易。一种方法看起来像这样:

class Program
{
    const int flipCount = 40;
    const long counterMax = (long)1 << flipCount;

    static void Main(string[] args)
    {
        for (long flipSequence = 0; flipSequence < counterMax; flipSequence++)
        {
            DisplayFlips(flipSequence);
        }
    }

    private static readonly StringBuilder sb = new StringBuilder(flipCount);

    private static void DisplayFlips(long flipSequence)
    {
        sb.Clear();

        for (int i = 0; i < flipCount; i++)
        {
            sb.Append((flipSequence & 1) != 0 ? 'T' : 'H');
            flipSequence >>= 1;
        }

        Console.WriteLine(sb);
    }
}