Excel VBA 的 LIFO(堆栈)算法/类
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4871485/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
LIFO (Stack) Algorithm/Class for Excel VBA
提问by BlackLabrador
I'm looking to implement a "Stack" Class in VBA for Excel. I want to use a Last In First Out structure. Does anyone came across this problem before ? Do you know external libraries handling structure such as Stack, Hastable, Vector... (apart the original Excel Collection etc...)
我希望在 VBA for Excel 中实现一个“堆栈”类。我想使用后进先出结构。有没有人遇到过这个问题?您是否知道外部库处理结构,例如 Stack、Hastable、Vector...(除了原始的 Excel Collection 等...)
Thanks
谢谢
回答by bruce
Here is a very simple stack class.
这是一个非常简单的堆栈类。
Option Explicit
Dim pStack As Collection
Public Function Pop() As Variant
With pStack
If .Count > 0 Then
Pop = .Item(.Count)
.Remove .Count
End If
End With
End Function
Public Function Push(newItem As Variant) As Variant
With pStack
.Add newItem
Push = .Item(.Count)
End With
End Function
Public Sub init()
Set pStack = New Collection
End Sub
Test it
测试一下
Option Explicit
Sub test()
Dim cs As New cStack
Dim i As Long
Set cs = New cStack
With cs
.init
For i = 1 To 10
Debug.Print CStr(.Push(i))
Next i
For i = 1 To 10
Debug.Print CStr(.Pop)
Next i
End With
End Sub
Bruce
布鲁斯
回答by jtolle
Bruce McKinney provided code for a Stack, List, and Vector in this book (it was VB5(!), but that probably doesn't matter much):
Bruce McKinney 在本书中提供了 Stack、List 和 Vector 的代码(它是 VB5(!),但这可能无关紧要):
http://www.amazon.com/Hardcore-Visual-Basic-Bruce-McKinney/dp/1572314222
http://www.amazon.com/Hardcore-Visual-Basic-Bruce-McKinney/dp/1572314222
(It's out of print, but used copies are cheap.)
(它已经绝版了,但使用过的副本很便宜。)
The source code appears to be available here:
源代码似乎可以在这里找到:
http://vb.mvps.org/hardweb/mckinney2a.htm#2
http://vb.mvps.org/hardweb/mckinney2a.htm#2
(Caveat - I've never used any of his code, but I know he's a highly regarded, long-time VB expert, and his book was included on MSDN for a long time.)
(警告 - 我从未使用过他的任何代码,但我知道他是一位备受推崇的长期 VB 专家,并且他的书在 MSDN 上收录了很长时间。)
I'm sure there are also many different implementations for these things floating around the internet, but I don't know if any of them are widely used by anybody but their authors.
我敢肯定,这些东西在互联网上也有许多不同的实现,但我不知道其中是否有任何一个被除作者之外的任何人广泛使用。
Of course, none of this stuff is that hard to write your own code for, given that VBA supports resizeable arrays (most of the way to a vector) and provides a built-in Collection class (most of the way to a list). Charles William's answer for a stack is about all the info you need. Just provide your own wrapper around either an array or a Collection, but the code inside can be relatively trivial.
当然,考虑到 VBA 支持可调整大小的数组(大多数情况下是向量)并提供内置 Collection 类(大多数情况下是列表),因此编写自己的代码并不难。Charles William 对堆栈的回答是关于您需要的所有信息。只需为数组或集合提供您自己的包装器,但其中的代码可能相对简单。
For a hashtable, the MS Scripting Runtime includes a Dictionary class that basically is one. See:
对于哈希表,MS Scripting Runtime 包括一个基本上是一个的 Dictionary 类。看:
回答by Charles Williams
I do not know of any external VBA libraries for these structures. For my procedure-call stack I just use a global array and array pointer with Push and Pop methods.
我不知道这些结构的任何外部 VBA 库。对于我的过程调用堆栈,我只使用具有 Push 和 Pop 方法的全局数组和数组指针。
回答by Espen Rosenquist
You can use the class Stack in System.Collections, as you can use Queue and others. Just search for vb.net stack for documentation. I have not tried all methods (e.g. Getenumerator - I don't know how to use an iterator, if at all possible in VBA). Using a stack or a queue gives you some nice benefits, normally not so easy in VBA. You can use
您可以在 System.Collections 中使用 Stack 类,就像使用 Queue 和其他类一样。只需在 vb.net 堆栈中搜索文档即可。我还没有尝试过所有方法(例如 Getenumerator - 我不知道如何使用迭代器,如果可能的话在 VBA 中)。使用堆栈或队列会给你带来一些好处,在 VBA 中通常不是那么容易。您可以使用
anArray = myStack.ToArray
EVEN if the stack is empty (Returns an array of size 0 to -1).
即使堆栈为空(返回大小为 0 到 -1 的数组)。
Using a custom Collections Object, it works very fast due to its simplicity and can easily be rewritten (e.g. to only handle strongly typed varibles). You might want to make a check for empty stack. If you try to use Pop on an empty stack, VBA will not handle it gracefully, as all null-objects. I found it more reasonable to use:
使用自定义的集合对象,由于其简单性,它的工作速度非常快,并且可以轻松重写(例如,仅处理强类型变量)。您可能想要检查空堆栈。如果您尝试在空堆栈上使用 Pop,VBA 将不会像所有空对象一样优雅地处理它。我发现使用更合理:
If myStack.Count > 0 Then
from the function using the stack, instead of baking it into clsStack.Pop. If you bake it into the class, a call to Pop can return a value of chosen type - of course you can use this to handle empty values, but you get much more grief that way.
从使用堆栈的函数中,而不是将其烘焙到 clsStack.Pop 中。如果你把它加入到类中,对 Pop 的调用可以返回一个选定类型的值——当然你可以用它来处理空值,但那样你会更加痛苦。
An example of use:
使用示例:
Private Sub TestStack()
Dim i as long
Dim myStack as clsStack
Set myStack = New clsStack
For i = 1 to 2
myStack.Push i
Next
For i = 1 to 3
If myStack.Count > 0 Then
Debug.Print myStack.Pop
Else
Debug.Print "Stack is empty"
End If
Next
Set myStack = Nothing
End Sub
Using a LIFO-stack can be extremely helpful!
使用 LIFO 堆栈非常有用!
Class clsStack
类 clsStack
Dim pStack as Object
Private Sub Class_Initialize()
set pStack = CreateObject("System.Collections.Stack")
End Sub
Public Function Push(Value as Variant)
pStack.Push Value
End Function
Public Function Pop() As Variant
Pop = pStack.Pop
End Function
Public Function Count() as long
Count = pstack.Count
End Function
Public Function ToArray() As Variant()
ToArray = pStack.ToArray()
End Function
Public Function GetHashCode() As Integer
GetHashCode = pStack.GetHashCode
End Function
Public Function Clear()
pStack.Clear
End Function
Private Sub Class_terminate()
If (Not pStack Is Nothing) Then
pStack.Clear
End If
Set pStack = Nothing
End Sub