何时在C#中使用Stack <t>集合?</t>

时间:2012-01-06 22:37:39

标签: c# data-structures

我确实理解Stack()Stack<T>是如何工作的,但我真的看不到阵列List<T>IEnumerable<T>不是更好的情况更容易的选择。

任何人都可以向我提供使用Stack<T>的真实世界示例吗?

12 个答案:

答案 0 :(得分:10)

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

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

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

使用具有更多细化功能的类有助于限制我们使用它的方式。

当整个应用程序在适当的抽象级别编码时,它只是更好

Stack是其中一个类。

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

如果我正在模拟一个自助餐厅,那么Stack对于那堆盘子来说是完美的。从顶部进入和离开堆栈。不是中间,不是结束;只是顶部。一堆。我只能使用Push()和Pop()板,这使得代码更加简单明了。

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

答案 1 :(得分:4)

深度优先搜索(DFS)是使用堆栈的一个很好的真实示例。

http://www.cs.toronto.edu/~heap/270F02/node36.html

答案 2 :(得分:3)

Depth first tree traversal。与队列相反,用于广度优先树遍历。


管理向用户展示不同的屏幕。显示一个屏幕将其推送到堆栈,然后“返回”弹出它。画出顶部屏幕。


如果你想要一个可以添加东西的集合,并且总是知道什么时候你知道它是最近添加的东西。


实施撤消/重做功能。

答案 3 :(得分:2)

如果你进行expression evaluation和语法分析,堆栈可能是有用的数据结构。

答案 4 :(得分:2)

通过控制堆栈上和堆栈外的本地数据,您可以更轻松地将递归方法重写为迭代对应方法。使用堆栈Jon Skeet查看here的排序。

答案 5 :(得分:1)

这是我使用Stack的一种方式:

我有一个类似页面的向导,其中有5个用户控件需要按特定顺序显示和处理,用户应该能够在任何时候按顺序返回到最后一页。

我使用基于堆栈的状态机来跟踪用户在向导中的进度。

每次他们向前移动时,我都会将状态机的状态推送到会话存储堆栈中,如果他们请求返回,我会弹出顶部值并将机器设置为新的顶部堆栈值。 (反过来,显示并加载适当的控件)

还有一个:

我必须为一些非常自定义的服务器应用程序构建安装应用程序。我最终做的是将安装的每个步骤分解为它自己的通用组件,即复制文件的组件,写入注册表值的组件等。每个组件都必须使用以下方法:执行安装操作,撤消安装操作。

安装的每一步,组件都被推入堆栈。

现在,在任何时候我都有错误,我们只是将每个组件从堆栈中弹出,并运行撤消操作,为我们提供精细的安装事务。

Stack是你的朋友!

答案 6 :(得分:1)

Stack and Queue在内部使用数组。如果您以智能方式使用数组,那么您已经在堆栈或队列中使用它们的可能性很大。通常你需要在Stack和Queue之间做出决定。 需要堆栈的典型示例是depth first search。如果将集合更改为队列,则表示已实现广度优先搜索。

另一个例子是繁重的多线程,如果处理顺序不相关,您可以通过堆栈在生产者和消费者之间传递数据。这背后的基本原理是,如果要处理大量数据,CPU最好使用最新添加的数据块在另一个线程上进一步处理,以获得更好的缓存局部性。

这个名单继续......

答案 7 :(得分:1)

堆栈经常用于文本解析算法,例如“4 + 5 + 6”的评估。有关使用堆栈解析文本的应用程序的实际示例,请参阅HTMLAgilityPack。该组件用于解析HTML,它包含源代码,因此您可以看到堆栈的使用方式和位置......

答案 8 :(得分:1)

将表达式从中缀表示法转换为前缀表示法时,

堆栈非常有用。例如:

a + b(+ a b)

答案 9 :(得分:0)

我会说如果你在概念上建模一些东西。假设你正在塑造一个小而深的抽屉,你正在把书放在抽屉里。这将遵循“先进先出”范式,这是一般的叠加点。

您没有书籍清单或某种枚举 - 您对它们有特定的排序......即,与它们的添加顺序相反。

答案 10 :(得分:0)

Stack<T>的功能看起来似乎是List<T>的一个子集(有一些重命名的方法),所以我同意它本身似乎不是最有用的集合。当在算法内部使用时,List<T>可以轻松替代它,即使这可能稍微不那么惯用。

只有在公开公开时才需要强制执行堆栈行为。但是在这种情况下,通常更好的方法是在内部集合上暴露某种包装器,所以它对它来说似乎并不是非常有用。我当然会看到用于IStack<T>接口,但不是对于简单的集合类Stack<T>来说非常重要。

我的结论是,我不会在框架中包含Stack<T>类,只是IStack<T>接口。 BCL系列通常看起来不是很好。

另一方面,

ConcurrentStack<T>似乎更有用。

答案 11 :(得分:0)

跟踪浏览器历史记录是堆栈的用途。此外,&#34;撤消&#34;用于编辑等 同样,一些仓库控制系统使用堆栈和队列来管理需要为货物选择物品的订单。