LIFO (Stack) Алгоритм / Класс для Excel VBA - PullRequest
7 голосов
/ 02 февраля 2011

Я собираюсь реализовать класс "Stack" в VBA для Excel. Я хочу использовать структуру Last In First Out. Кто-нибудь сталкивался с этой проблемой раньше? Знаете ли вы структуру обработки внешних библиотек, такую ​​как Stack, Hastable, Vector ... (кроме оригинальной коллекции Excel и т.д ...)

Спасибо

Ответы [ 4 ]

10 голосов
/ 02 февраля 2011

Вот очень простой класс стека.

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

Проверьте это

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

1 голос
/ 02 февраля 2011

Брюс МакКинни предоставил код для стека, списка и вектора в этой книге (это был VB5 (!), Но это, вероятно, не имеет большого значения):

http://www.amazon.com/Hardcore-Visual-Basic-Bruce-McKinney/dp/1572314222

(Распродано, но использованные копии дешевы.)

Исходный код доступен здесь:

http://vb.mvps.org/hardweb/mckinney2a.htm#2

(Предостережение - я никогда не использовал ни один из его кодов, но я знаю, что он очень уважаемый, давний эксперт по VB, и его книга долгое время была включена в MSDN.)

Я уверен, что есть много разных реализаций для этих вещей, распространяющихся по Интернету, но я не знаю, широко ли кто-либо из них используется кем-либо, кроме их авторов.

Конечно, ни одна из этих вещей не является такой сложной для написания вашего собственного кода, учитывая, что VBA поддерживает изменяемые размеры массивов (в большинстве случаев для вектора) и предоставляет встроенный класс Collection (в большинстве случаев для список). Ответ Чарльза Уильяма за стек - обо всей необходимой информации. Просто предоставьте свою собственную обертку вокруг массива или коллекции, но код внутри может быть относительно тривиальным.

Для хеш-таблицы MS Scripting Runtime включает класс Dictionary, который в основном равен единице. Смотри:

Хеш-таблица / Ассоциативный массив в VBA

1 голос
/ 02 февраля 2011

Я не знаю каких-либо внешних библиотек VBA для этих структур. Для моего стека вызовов процедур я просто использую глобальный массив и указатель массива с методами Push и Pop.

0 голосов
/ 08 июня 2016

Вы можете использовать класс Stack в System.Collections, как вы можете использовать Queue и другие.Просто найдите стек vb.net для документации.Я не пробовал все методы (например, Getenumerator - я не знаю, как использовать итератор, если это вообще возможно в VBA).Использование стека или очереди дает вам хорошие преимущества, которые обычно не так просты в VBA.Вы можете использовать

anArray = myStack.ToArray

EVEN, если стек пуст (возвращает массив размером от 0 до -1).

Используя пользовательский объект коллекций, он работает очень быстро благодаря своей простотеи может быть легко переписан (например, обрабатывать только строго типизированные переменные).Вы можете проверить наличие пустого стека.Если вы попытаетесь использовать Pop в пустом стеке, VBA не будет корректно обрабатывать его, как все нулевые объекты.Я нашел более разумным использовать:

If myStack.Count > 0 Then

из функции, использующей стек, вместо того, чтобы запекать ее в clsStack.Pop.Если вы запечете это в классе, вызов Pop может вернуть значение выбранного типа - конечно, вы можете использовать это для обработки пустых значений, но вы получите гораздо больше горя в этом случае.

Пример использования:

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

Использование LIFO-стека может быть чрезвычайно полезным!

Класс 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...