繁体   English   中英

我如何知道何时使用堆栈而不是其他集合?

[英]How do I know when to use a Stack instead of other Collections?

这是我想知道的更普遍问题的前奏:

我最近在做一个编程挑战,你应该编写一个方法来检查给定字符串中括号的平衡。 该方法应该接受一个字符串并返回第一个额外的')'或'('括号所在的索引,或者如果它们相等,则返回字符串的长度。一些示例输入如下:")( asdf)))" - 0; “((((asdf)))” - 0;“((((asdf))” - 1; “(ab)(((cd)(asdf)” - 5。

我首先尝试为括号的每个方向创建一个列表,它将所有括号的索引存储在字符串中。 然后,我将遍历字符串中的每个字符,如果匹配,则将其索引添加到任一列表中,并检查它们是否已经不匹配。 这种策略适用于某些情况,但某些情况仍然失败。 感觉卡住了,我检查了挑战中的其他一些答案,看到他们使用堆栈来存储左括号的索引,必要时他们会推送和弹出。 这种方法效果好多了,好多了,我觉得有点尴尬,因为我自己没有想到它。

这让我想到了我的问题......我怎么知道什么时候最好使用堆栈而不是其他各种集合? 有哪些常见的事情可能会提示我在任何其他集合上使用堆栈?

我知道 Stacks 是如何工作的,并在一些教程等中使用过它们,但从来没有真正发现自己在现实世界中使用过它们……在看到他们在挑战中创造的简单性之后,我觉得我错过了一些机会制作更简单/更好的代码。

就像其他人所说的那样,当您需要您的集合具有后进先出 (LIFO) 行为时,就会使用堆栈。 每当您处理有关某事物“最顶层”或“最新”的信息时,这都会体现出来。

您谈到的例子就是一个很好的例子,为了最有效地处理括号组,您将左括号存储在一个集合中,并在遇到右括号时删除最近的左括号。

堆栈也可用于某些树/图遍历算法。 深度优先方法将使用堆栈来存储仍需要遍历的节点列表,因为使用堆栈与一致的插入模式相结合具有在树的宽度上搜索树的深度的固有属性。 (另一方面,广度优先遍历算法使用队列代替。)

另一种可能的用途是一副纸牌。 对于大多数游戏,您并不关心牌组中央某处的内容。 当玩家需要一张牌时,他们只需从顶部抽一张牌。 由于这完全模仿了堆栈的行为,因此堆栈将是此类应用程序的一个可能考虑因素。 (毕竟,“套牌”只是一堆纸牌。)

还有很多其他应用程序。 它们的共同点是,它们适用于您想要在集合的最顶层或最新项目上需要的时候。 了解您的特定应用程序是否会从堆栈中受益只需要一些了解如何识别这些场景的经验。

编辑:哦,当然还有 .NET 用于方法范围和临时变量堆栈。 它与数据结构同名并非巧合。 当在方法中声明变量时,它的内存分配被添加到堆栈的末尾。 然后当方法返回并且变量超出范围时,该内存将从堆栈中弹出并交给垃圾收集器。

堆栈的另一个好例子是当你输入一些你最终会离开的“上下文”时。 如果您存储一些仅在两个时刻之间有效并且一旦离开此“上下文”就会被遗忘的信息,则更是如此。

在括号示例中,您在匹配时“输入” (并且在匹配时“离开”括号块) 当您在括号内时,您需要记住起始(的位置(以防它没有匹配) ,但是一旦找到匹配的) ,您就可以忘记该信息。

当您需要使用 LIFO(后进先出)时,例如在调用函数或使用后缀表示法时。

你可以在这里看到更多的 java 例子!

以下是从 SO 问题中复制的选定答案: When to use the Stack collection in C#?

PS我不是抄袭。 我写了这个答案。


理想情况下,您使用或根据需要创建反映事物在现实世界中如何工作的类,即您在代码中建模的事物。 这些类为我们提供了一定程度的抽象,因此我们可以根据我们正在建模/模拟的内容进行编码。 此外,在编写一些复杂的东西时,使用熟悉的范例会有所帮助。 也就是说:哦,这个 Fuzzinator 类使用了一个 Stack。 我知道堆栈是什么以及它是如何工作的。

其次,更高级别的抽象类为我们提供了有效的代码(我们假设 .NET 框架已经过测试),并为我们节省了重新发明轮子的时间和痛苦。

第三,代码更容易阅读、更容易理解、更容易改变等。 它更易于维护。

使用具有更精细功能的类有助于限制我们在使用它时可能会搞砸的情况。

总的来说,当您的应用程序在适当的抽象级别进行编码时,它会变得更好。

Stack 就是这些类之一。

我的 HP-41X 计算器使用堆栈进行运算 这种计算方式称为 RPN - 逆波兰表示法。

如果我在模拟自助餐厅,Stack 将非常适合那叠盘子 盘子从顶部上下堆叠。 不是中间,不是结尾; 只是顶部。 一个堆栈。 我只能 Push() 和 Pop() 板块,这使得代码更加简单明了。

或者,想象一下使用 C# 等效的亚原子粒子进行编码 - 泛型集合或泛型 IEnumerable 等。我最终使用具有通用名称的通用实用程序方法和属性,这些参数具有多变量数量的参数,这些总体上掩盖了我我在堆盘子。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM