2013-12-09 34 views
7

在C#,是有辦法推一個堆棧到另一個棧不通過堆元件迭代?如果不是,我應該使用更好的數據結構嗎?在Java中,你可以這樣做:推堆疊到另一個棧

stack1.addAll(stack2) 

我希望能找到C#的模擬...

+0

Parhaps有點遲鈍,但是投射到'ArrayList',然後使用http://msdn.microsoft.com/en-us/library/system.collections.arraylist.insertrange(v=vs.110).aspx然後投回到堆棧? – rdodev

+0

重複? http://stackoverflow.com/questions/1594264/pushing-items-into-stack-with-linq –

+0

可以將每個堆棧複製到數組,然後使用Array.Copy來合併數組,然後將數組加載到ctor中的新堆棧但我想我會循環。 – Paparazzi

回答

3

0.1安全解決方案 - 可拓方法

public static class Util { 
     public static void AddAll<T>(this Stack<T> stack1, Stack<T> stack2) { 
      T[] arr = new T[stack2.Count]; 
      stack2.CopyTo(arr, 0); 

      for (int i = arr.Length - 1; i >= 0; i--) { 
       stack1.Push(arr[i]); 
      } 
     } 
    } 

也許最好是創建一個擴展方法。請注意,我把第一棧「上面」其他棧因此由循環說話arr.Length,1比0。因此,這段代碼:

Stack<int> x = new Stack<int>(); 
    x.Push(1); 
    x.Push(2); 

    Stack<int> y = new Stack<int>(); 
    y.Push(3); 
    y.Push(4);   

    x.AddAll(y); 

會導致X爲:4,3 ,2,1。如果你推1,2,3,4,這是你所期望的。當然,如果你通過你的第二堆是循環和實際流行元素,然後按那些第一堆棧,你最終會得到1,2,4,3。再次,按照您認爲合適的方式修改for循環。或者你可以添加另一個參數來指定你想要的行爲。我沒有Java方便,所以我不知道他們做什麼。

話雖如此,你可能做到這一點,但我不作任何保證,它會繼續工作。 MS可以隨時更改調用ToList時堆棧工作方式的默認行爲。但是,這是更短,並且在機.NET 4.5的工作原理與上面相同的擴展方法:

1號線Linq的解決方案:

y.Reverse().ToList().ForEach(item => x.Push(item)); 
+0

奇怪的是[MSDN文檔](http://msdn.microsoft.com/en-us/library/yfw8w9at.aspx)沒有明確指定堆棧枚舉的順序,雖然它*有*例。不過,ToArray方法確實指定了LIFO順序。 – Rawling

+0

我喜歡你的安全解決方案。這正是我想要的行爲,同時仍然在使用堆棧(當你像堆棧一樣進行堆棧時,它們在概念上更好)。 – ryan0

1

addAll將只是一個foreach循環,增加了所有項目的簡便方法。真的是沒有什麼可以除此之外做到:

foreach(var item in stack2) 
    stack1.Push(item); 

如果你做到這一點特別頻繁,你可以添加一個擴展方法吧,爲自己的方便。

+0

是的,我現在看到那些AddRange/AddAll方法都是迭代的。我想我是在方便之後,而不是真正的表現。 – ryan0

1

在你的問題,想要做這種「不通過堆棧元素迭代」基本上是指一個LinkedList基於堆在那裏你會剛剛加入的第一個和最後一個元素,以堆在固定時間內結合。

但是,除非您有使用LinkedList的特定原因,否則對迭代基於陣列(基於陣列的(基於List))的堆棧元素可能更好。

至於具體的實施得好,你應該清楚你是否要添加第二個堆棧首先在同一堆疊順序或通過被彈出被逆轉到第一堆棧。

0

這並不意味着要與當前的.NET堆棧執行完成。

爲了使堆棧的內容被「嫁接」到另一疊的末端不反覆,雖然它的元素內部實現細節Stack類並將它們存儲在內存中如何必須要知道。基於封裝原則,這些信息是「正式」的,只有在Stack類本身內部才能知道。 。NET的堆棧不公開方法來做到這一點,所以沒有使用反射,就沒有辦法像OP請求那樣做。

可以想象,您可以使用反射來追加到另一個堆棧的內容的一個堆棧的內部數組,並更新存儲堆棧長度的字段,但這將高度依賴於可以更改的堆棧類的實現在未來的版本框架中沒有警告。

如果你真的需要一個堆棧可以做到這一點,你可以從頭開始編寫自己的Stack類或簡單地使用另一個集合像ArrayListLinkedList其中有你想要添加PushPop擴展方法,它們的方法。

相關問題