【问题标题】:Getting a random number that isn't the last one? [duplicate]得到一个不是最后一个的随机数? [复制]
【发布时间】:2017-10-21 16:47:36
【问题描述】:

所以我正在尝试做一个随机提示生成器,很明显,至少在所有提示都被看到之前不应该显示相同的提示

private string getRandomTip()
{
    List<string> Titles = new List<string> {
    "You can copy the result by clicking over it",
    "Remember to press Ctrl + Z if you messed up",
    "Check web.com to update the app"};

    Random rnd = new Random();

    int Index = rnd.Next(0, Titles.Count);
    string randomString = Titles[Index];
    Titles.RemoveAt(Index);

    return randomString;
}

但由于某种原因,这会连续两次或多次重复提示。我认为我可以生成随机数,直到我得到一个不是最后一个的,但这看起来像是一个糟糕的优化代码。

你能帮帮我吗?

编辑:好的,非常感谢你们,我现在正在尝试这个

    public List<string> Titles = new List<string> {
        "You can copy the result by clicking over it",
        "This calculator was created by Glow on 21/10/17",
        "Click on this tip to show the next one"};

    private string getRandomTip()
    {
        string randomString;

        if (Titles.Count > 0) {
            Random rnd = new Random();

            int Index = rnd.Next(0, Titles.Count);
            randomString = Titles[Index];
            Titles.RemoveAt(Index);
        }
        else
        {
            randomString = "Those were all the tips!";
        }
        return randomString;
    }

而且效果很好。再次感谢:)

【问题讨论】:

  • 每次调用该方法时,列表都会重新初始化。从此临时列表中删除不会影响下次通话时发生的任何事情。它将再次充满所有这些。您需要将列表存储在方法之外。
  • 推荐你read the documentation。使用默认构造函数(相同的种子)创建一个新的随机数将创建相同的随机数序列。第 1 节的第 3 段将引导您朝着正确的方向前进。
  • 是的,非常感谢你,我已经更新了它,看起来它现在可以工作了。谢谢:)
  • 如果重复还不够……随机数不能是唯一的,但它不会阻止人们尝试-bing.com/search?q=c%23+random+unique+numbers

标签: c# winforms


【解决方案1】:

这里有两个问题。首先,每次调用 GetRandomTip() 方法时都会重新初始化列表,因此它总是能够从每个可能的提示中输出,并忽略对 RemoveAt() 的调用。您可以做的是仅在列表有 0 个元素时重新填充列表。这样一来,您就可以确定所有提示都会在停止列表之前显示一次。

第二个是你不应该每次都重新初始化你的Random 对象。您可能想参考this post 了解更多信息。

这是您的代码,已修改。它应该会产生更好的结果。

private class Test
{
    readonly Random Rnd = new Random();
    private List<string> _titles = new List<string>(); // Init the list with 0 elements, it will be filled-in on the first call to `GetRandomTip`

    private string GetRandomTip()
    {
        // fill the list if it's empty
        if(_titles.Count == 0) 
        {
            _titles = new List<string>
            {
                "You can copy the result by clicking over it",
                "Remember to press Ctrl + Z if you messed up",
                "Check web.com to update the app"
            };
        }

        int index = Rnd.Next(0, _titles.Count);
        string randomString = _titles[index];
        _titles.RemoveAt(index);

        return randomString;
    }
}

【讨论】:

  • 这样更好,谢谢。我曾想过使用“这些都是技巧!”但重新填写列表看起来更好。非常感谢
  • 我认为最好一遍又一遍地显示它们,以防您的用户错过一些;-)
  • 如果您的问题得到解决,请考虑通过单击复选标记接受它。这向更广泛的社区表明您已经找到了解决方案,并为回答者和您自己提供了一些声誉。没有义务这样做。
  • 当然对不起哈哈
【解决方案2】:

您必须在您的方法之外初始化Random 对象和列表。否则每次重新输入方法时列表都会被填满。

一种解决方案可能是:

public class Tip
{
    private readonly IEnumerable<string> _originalTips = new List<string>
    {
        "You can copy the result by clicking over it.",
        "Remember to press Ctrl + Z if you messed up.",
        "Check web.com to update the app."
    };

    private IList<string> _availableTips;
    private Random _random;



    public Tip()
    {
        _availableTips = _originalTips.ToList();
        _random = new Random();
    }



    public string GetRandomTip()
    {
        if (!_availableTips.Any())
        {
            _availableTips = _originalTips.ToList();
        }

        int index = _random.Next(0, _availableTips.Count);

        string tip = _availableTips[index];

        _availableTips.RemoveAt(index);

        return tip;
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-11-24
    • 1970-01-01
    • 1970-01-01
    • 2014-05-14
    • 1970-01-01
    • 2019-10-20
    • 1970-01-01
    • 2016-09-10
    相关资源
    最近更新 更多