2013-11-03 20 views
-1

我需要使用Reverse方法來反轉堆棧的順序。如何使用Stack的Reverse方法?

但我已經試過這一點,這是行不通的:

Dim StackObject As New Stack(Of String) 
    StackObject.Push("S") 
    StackObject.Push("T") 
    StackObject.Push("A") 
    StackObject.Push("C") 
    StackObject.Push("K") 

    StackObject = StackObject.Reverse.Cast(Of String)() ' <-- InvalidCastException 

    For Each str As String In StackObject 
     MsgBox(str) 
    Next 

我寫了這個通用函數來扭轉堆棧,但我想用Reverse的方法做它,而不是所有這些unnecesary代碼:

Private Function Reverse_Stack(Of T)(stack As Stack(Of T)) 

    Dim new_stack As New Stack(Of T) 

    While Not stack.Count = 0 
     new_stack.Push(stack.Pop) 
    End While 

    Return new_stack 

End Function 
+3

請請不要使用短語「不工作」。我們已經知道這是行不通的,因爲你在這裏張貼。發佈預期行爲和實際行爲。這很簡單。對於像你一樣有業力的人來說,我很驚訝你沒有做正確的事情。 – siride

+0

使用短語「不起作用」,應該處以死刑。 – siride

+0

@siride很顯然,問題出在反向指令'StackObject = StackObject.Reverse.Cast(Of String)()'你只需要讀取我的問題的標題。調試器會拋出一個轉換異常。真的,人們一無所獲。 – ElektroStudios

回答

4

爲什麼StackObject = StackObject.Reverse().Cast(Of String)()會拋出異常?

Reverse的是,在這種情況下返回一個IEnumerable(Of String)(順便說一下,意味着Cast(Of String)是多餘的),因此不能直接結果分配給Stack(Of String)類型的變量一個LINQ擴展方法。

您可以使用Option Strict語句在編譯時而不是在運行時捕獲此錯誤。

那麼,我該如何取消Stack(Of T)

只需使用需要一個IEnumerable(Of T)Stack(Of T) constructor,給它的堆棧扭轉:

Private Function Reverse_Stack(Of T)(stack As Stack(Of T)) As Stack(Of T) 
    Return New Stack(Of T)(stack) 
End Function 

你甚至可能使這是一個擴展方法,取代了LINQ Reverse

<Extension> 
Public Function Reverse(Of T)(stack As Stack(Of T)) As Stack(Of T) 
    Return New Stack(Of T)(stack) 
End Function 

現在你可以寫出StackObject = StackObject.Reverse(),沒有錯誤。

這是如何工作的?

Stack(Of T).GetEnumerator()返回的順序中的元素,它們將從堆棧中彈出,並且Stack(Of T)構造推壓所述給定序列的元素到堆棧中的元素出現在序列中的順序。因此,舊堆棧頂部的元素成爲新堆棧底部的元素。

+0

太棒了,謝謝。真正的問題是用你的解決方案來解決的,但是我想知道如何使用好的反轉方法來堆棧,如果你可以舉個例子,如果沒有問題的話。 – ElektroStudios

+0

@ElektroStudios:不幸的是,正如dasblinkenlight所解釋的那樣,'Reverse'是一個擴展方法,它返回一個'IEnumerable(Of T)',而不是'Stack(Of T)'。所以,如果你想要一個反轉的'Stack(Of T)',你需要寫一些像'New Stack(Of String)(stack.Reverse()。Reverse())',這是毫無意義的,對嗎? –

+0

理解,謝謝 – ElektroStudios

3

與此線

StackObject = StackObject.Reverse.Cast(Of String)() 

的問題是,ReverseIEnumerable(Of T)擴展方法。它會產生另一個IEnumerable(Of T)Cast(Of String)的調用是不必要的,因爲序列已經包含字符串。

可以使用顛倒堆疊這樣的:

For Each str As String In StackObject.Reverse() 
    MsgBox(str) 
Next 

當堆棧用作IEnumerable(Of T),它產生相對於插入的順序相反的順序的項目。因此,上述循環將產生適當插入序列中的字母,即S,T,A,C, K

如果你想從現有的堆棧中創建一個新的堆棧,只需要以相反的順序,將堆棧傳遞給堆棧構造器即可。由於堆棧以反向插入順序生成值(如上所述),因此新堆棧將與原始堆棧相反。

+0

但如何使用反轉方法的堆棧?這將拋出相同的轉換異常StackObject = CType(StackObject.Reverse,Stack(Of String)) – ElektroStudios

+2

@ElektroStudios沒有專門爲堆棧構建的'Reverse'方法 - 它是IEnumerable(Of T)的*擴展*方法' ,你不能將它轉換爲'Stack(of T)'。 – dasblinkenlight

相關問題