【问题标题】:Generating Random Unique items from a string list [duplicate]从字符串列表生成随机唯一项[重复]
【发布时间】:2019-04-13 12:47:17
【问题描述】:

我有一副牌的字符串列表,字符串是这样的,A-DIAMONDS、2-CLUBS 等。

我希望能够从此列表中随机生成 5 个唯一项目。

我知道如何在 python 中使用 Random.sample(5) 执行此操作,但尝试在 C# 中找到解决方案。一切似乎都在生成一个随机数,把它放在一个列表中,生成另一个随机数,对照列表检查它,它工作正常。

在 C# 中有更紧凑的方法吗?

这是我使用 Linq 进行洗牌后的完整代码。

    class Program
{
    static void Main(string[] args)
    {
        string [] cardValues = { "A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K" };
        string [] cardSuites = { "HEARTS", "CLUBS", "DIAMONDS", "SPADES" };
        List<string> deckOfCards = new List<string>();

        foreach(string cardsuit in cardSuites)
        {
            foreach(string cardvalues in cardValues)
            {
                deckOfCards.Add(cardvalues + "-" + cardsuit);
            }

        }

        for(int i = 0; i <= 10; i++)
        {
            List<string> pokerHand = new List<string>();
            Random rand = new Random();
            deckOfCards = deckOfCards.Select(x => new { card = x, rand = rand.Next() }).OrderBy(x => x.rand).Select(x => x.card).ToList();
            for(int x = 0; x < 5; x++)
            {
                pokerHand.Add(deckOfCards[x]);
            }
            Console.WriteLine(String.Join(", ", pokerHand));
        }


        Console.ReadLine();
    }
}

}

【问题讨论】:

  • 为什么要使用链接来实现洗牌?
  • 你能再补充一点吗?这是一个有效的问题,但你会用什么来代替
  • 我把 Q 作为一个骗子关闭了。洗牌是这里经常讨论的话题。受骗者是众多可能的候选人之一。
  • 我也怀疑你接受的答案是否实现了统一的洗牌。

标签: c# random


【解决方案1】:

这是使用 linq 随机播放的一种方法。 5 张随机卡片是列表中的前 5 个项目。 :

    class Program
    {
        static void Main(string[] args)
        {
            List<string> deck = new List<string>() {
                "S2", "S3", "S4", "S5", "S6", "S7", "S8", "S9", "ST", "SJ", "SQ", "SK", "SA",
                "H2", "H3", "H4", "H5", "H6", "H7", "H8", "H9", "HT", "HJ", "HQ", "HK", "HA",
                "C2", "C3", "C4", "C5", "C6", "C7", "C8", "C9", "CT", "CJ", "CQ", "CK", "CA",
                "D2", "D3", "D4", "D5", "D6", "D7", "D8", "D9", "DT", "DJ", "DQ", "DK", "DA"
            };

            Random rand = new Random();

            deck = deck.Select(x => new { card = x, rand = rand.Next() }).OrderBy(x => x.rand).Select(x => x.card).ToList();
        }
    }

【讨论】:

  • 我认为这可行。所以你洗牌,然后你可以抓住前5张牌,因为它会是随机的。从来没有这样想过。我是 C# 新手,所以我需要研究其中一些方法的作用,以便我有更好的理解,但我喜欢它。非常感谢
  • 随机选择一张卡片,你必须检查你是否两次选择了同一张卡片。只需为每张卡片分配一个随机数,然后按随机数排序就容易得多。
  • 那么您选择所有元素,为每个元素分配一个随机数,然后对随机数进行排序,然后以随机数排序顺序将元素添加回列表?
  • 完全正确。我正在使用 linq 匿名方法创建一个二维数组 {card, random number} 然后最后从二维数组中删除卡片以创建一个一维字符串数组。
【解决方案2】:

您可以使用MoreLINQ。只需从 NuGet 安装它。 MoreLINQ 给你一个Shuffle 方法。因此,您可以执行以下操作:

List<Card> deck = GetDeck();
List<Card> randomFiveCards = deck.Shuffle().Take(5).ToList();

【讨论】:

  • 你能详细说明一下吗,GetDeck是什么
  • 这将是用项目填充deckOfCards 列表的方法。你必须用你自己的逻辑替换GetDeck() 来创建一个套牌。抱歉,如果这让您感到困惑。
【解决方案3】:

一个有效且高效的算法是在0n-1 之间选择一个随机索引(其中n 是卡片的数量),将最后一张卡片与该索引处的卡片交换。然后在0n-2 之间选择一个随机索引,并与该索引处的卡交换倒数第二张卡。

n-3n-4n-5 重复其他三遍,你随机选择的五张卡片将位于数组的末尾。

【讨论】:

    猜你喜欢
    • 2012-11-21
    • 2010-10-18
    • 1970-01-01
    • 2010-12-07
    • 1970-01-01
    • 2018-07-15
    • 1970-01-01
    相关资源
    最近更新 更多