Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/304.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在堆栈中弹出随机项_C# - Fatal编程技术网

C# 在堆栈中弹出随机项

C# 在堆栈中弹出随机项,c#,C#,我似乎不知道如何使用元素特性弹出堆栈中的项目。有人能告诉我怎么做吗 相关代码: Stack<Cards> stackOfCards = new Stack<Cards>(); 我以前曾将项目放入此堆栈中 Random random = new Random(); int randomNumber = random.Next(0, 52); for (int i = 0; i < 200; i++) { stackOfCards.ElementAt(ran

我似乎不知道如何使用元素特性弹出堆栈中的项目。有人能告诉我怎么做吗

相关代码:

Stack<Cards> stackOfCards = new Stack<Cards>();
我以前曾将项目放入此堆栈中

Random random = new Random();
int randomNumber = random.Next(0, 52);

for (int i = 0; i < 200; i++)
{
    stackOfCards.ElementAt(randomNumber);//how do i pop this?
}

另外,堆栈是从0开始还是从1开始?因此,对于一副牌来说,它是0-51还是1-52?

堆栈的全部要点是不弹出随机元素。如果需要从集合中删除随机项,请使用支持该集合的集合,如列表

堆栈是后进先出的后进先出集合,而不是随机访问集合

我建议阅读:

如果你需要在堆栈上随机放置一些东西,我建议如下:

List<Cards> wholeDeck = new List<Cards> { // initialize with a complete deck }
Random r = new Random();
Stack<Cards> stackOfCards = new Stack<Cards>();
while (wholeDeck.Count > 0) {
    var aCard = wholeDeck[r.Next(0,wholeDeck.Count)];     // grab a random card
    stackOfCards.Push(aCard);                              // push it on the stack
    wholeDeck.Remove(aCard);                              // remove it from the original list
}
自Servy收购它以来,关于效率的一点说明:Servy绝对正确,这不是最有效的洗牌方式。为什么?因为从列表中删除一个项目是开的,你必须做n次,所以总的来说是开2次。在Fisher-Yates算法中交换列表中的项目是O1,你会做n次,所以总的来说它是打开的。当然,您仍然需要将无序列表中的项目添加到将要打开的堆栈中,所以O2n。对于52张牌来说,这可能没有什么区别,这就是为什么我选择不去担心它,但是如果你有数百万张牌,或者你正在洗牌一百万副牌,那么这可能是需要担心的

现在我假设OP最初的问题是针对某类课程的,目标是学习一些关于收藏的知识,它们是如何工作的,它们有什么好处,我认为这确实带来了一个重要的比较。不同的收藏类型适用于不同的事物。列表为您提供了对列表中任何项目的快速、O1随机访问,这使它成为一种非常通用的集合类型。但这是有代价的。成本是删除和插入,有时添加到列表中要慢得多。从列表中删除项目时,必须重新组织列表,以便在删除项目后将每个项目向下移动一个位置,以便仍然可以快速对其编制索引。当您在某个任意索引处插入时,您必须将项目上移以腾出空间。当您添加到列表的末尾时,您可能需要调整.NET中的备份存储的大小。这是一个数组,用于腾出空间。实际上,插入操作可能需要复制整个集合。NET list类通过设置初始容量来解决此问题。当达到该容量时,它会将容量加倍,而不仅仅是再添加一个元素。所以,如果您需要一个集合,其中需要大量插入和删除项,那么列表可能不是最佳选择

那么Stack呢?Stack只允许您在集合中的一个位置添加push和remove pop,从而解决了插入和删除问题。这样,至少对于固定大小的堆栈,添加和删除是O1。这很好。但代价是你现在失去了以随机顺序访问收藏中物品的能力。因此,OP很难弄清楚如何在堆栈上洗牌。如果需要堆栈上的第n个项目,则必须将其上方的每个项目弹出到临时堆栈中,然后查看所需的项目,然后将删除的所有项目推回到堆栈上

另一种集合类型是链表。如果有对节点的引用和插入,则此集合的删除速度非常快,如果是双链接列表节点,则可以快速找到下一个和最后一个集合。但是查找第n个节点是打开的,因为您必须遍历集合,计算节点数才能找到它


其他集合具有其他属性,在选择正确的集合之前,了解您需要从集合中获得什么非常重要

我被告知使用一个堆栈来模拟一个发牌商。但首先我需要洗牌。你不能这样做,而我误解了别人对我的要求吗?@user3245390在将牌放入堆栈之前洗牌,而不是在放入堆栈之后。@user3245390:你可以从任何可IEnumerable的内容创建堆栈。因此,首先创建一个用随机卡片组初始化的列表,然后将其转换为如下堆栈:var myStackOfCards=new stackmylistofccards;如果这个答案允许的话,我会接受的。我似乎误解了他们让我做的事情,他们让我随机生成卡片,但他说,如果我用自己的方式解决这个问题就好了。谢谢大家的回答。@Servy:当然,当你将它们添加到堆栈中时,会将它们洗牌。堆栈不会按索引访问项目;无需定义它们是1索引还是零索引,因为您无法对给定位置的项执行任何操作。@Rikon ElementAt是LINQ方法,而不是堆栈方法。堆栈实现IEnumerable,因此它将迭代整个序列直到该元素。堆栈是从0还是从1开始也不堆栈没有索引,它们只显示当前项或顶部项。堆栈的任何给定实现都可能在内部具有
一个可索引的数据结构,但该索引没有暴露在堆栈的外部。为什么要从卡片组中取出随机卡片?不管怎样,你不应该只是从最上面开始吗?一旦你得到答案,把你的问题完全编辑成一个完全不同的问题是不合适的。