Push a stack onto another stack - c#

In C#, is there a way to push one Stack onto another Stack without iterating through the stack elements? If not, is there a better data structure I should be using? In Java you can do:
stack1.addAll(stack2)
I was hoping to find the C# analogue...

0. Safe Solution - Extension Method
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]);
}
}
}
Probably the best is to create an extension method. Note that I am putting the first stack "on top" of the other stack so to speak by looping from arr.Length-1 to 0. So this code:
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);
Will result in x being: 4,3,2,1. Which is what you would expect if you push 1,2,3,4. Of course, if you were to loop through your second stack and actually pop elements and then push those to the first stack, you would end up with 1,2,4,3. Again, modify the for loop as you see fit. Or you could add another parameter to specify which behavior you would like. I don't have Java handy, so I don't know what they do.
Having said that, you could do this, but I don't make any guarantees that it will continue to work. MS could always change the default behavior of how stack works when calling ToList. But, this is shorter, and on my machine with .NET 4.5 works the same as the extension method above:
1 Line Linq solution:
y.Reverse().ToList().ForEach(item => x.Push(item));

In your question, wanting to do this "without iterating through the stack elements" basically means a LinkedList-based stack where you would just join the first and last elements to combine stacks in constant time.
However, unless you've a very specific reason for using LinkedList, it's likely a better idea to just iterate over an array-based (List-based) stack elements.
As far as a specific implementation goes, you should probably clarify whether you want the second stack to be added to the first in the same stack order or to be reversed into the first stack by being popped out.

An addAll would just be a convenience method for a foreach loop that adds all of the items. There really isn't much you can do besides that:
foreach(var item in stack2)
stack1.Push(item);
If you do it particularly frequently you can add an extension method for it, for your own convenience.

This isn't meant to be done with the current .NET Stack implementation.
In order for the content of a Stack to be "grafted" onto the end of another Stack without iterating though its elements internal implementation details how the Stack class stores them in memory has to be known. Based on the principle of encapsulation this information is "officially" only know inside the Stack class itself. .NET's Stack does not expose methods to do this, so without using reflection there is no way to do it as the OP requested.
Conceivably you could use reflection to append to the internal array of one Stack the content of another Stack and also update the field that stores the stack length but this would be highly dependent on the implementation of the Stack class which could be changed in future versions of the framework without warning.
If you really need a Stack that can do this you could write your own Stack class from scratch or simply use another collection like ArrayList or LinkedList which have the method you want and add Push and Pop extension methods to them.

Related

Why does this recursive method cause a Stack Overflow error when it has no variables?

I have recursive method like this, which doesn't contain any variable. Why is it throwing a stack overflow exception?
class MainClass
{
static void Main() => Bark();
static void Bark() { Bark(); }
}
in the example above, I did not create any variables. If I create any variable(either as a parameter or inside a method), then this is understandable: many variables have been created in the thread's stack, and due to the lack of memory, I get an error.
I don't understand, is the method itself is also stored on the stack? Why am I getting the error?
The stack frame does not just contain parameters, it also contains a return address, so that the processor knows where to go back to.
Furthermore, the hidden this pointer is also a parameter. To remove that you would need a static function.
There is also the ebp or other stack-frame pointer, which can be pushed onto the stack for each call, depending on the exact calling convention.
So whatever you do, you will definitely get a stack overflow at some point, unless the compiler decides to perform tail-recursion.
If you were to debug this piece of code and look at the "call stack" window then you would see it attempt to add Bark to the call stack an infinite amount of times because the recursion has no end point.
I believe what you're expecting to see is tail recursion. Unfortunately C# compiler doesn't support it.

Stack of a stack c#

So I have a stack of a few stacks.
This is how I implemented the stack: public Stack<Stack<Baggage>> Trunk;
So trunk is supposed to hold multiple stacks of baggage (one baggage stack has a limited number of bags it can hold)
The question I have is, how would I write out the trunk stack.
Ive tried using the pop() function but on the console it writes out this: System.Collections.Generic.Stack1[TestDummy.Baggage]` I tried making an override ToString method in the baggage class but it doesn't work.
thank you for your help!
From what I understood, you are trying to print Trunk content to console. You must keep in mind that inside your Trunk stack there are another stacks, so you should pop a value from that stack too, to get it
Here is a simple example code:
foreach(var baggage in Trunk.Pop())
{
Console.WriteLine(baggage.Name);
}
Trunk.Pop() will take off stack from Trunk and foreach loop will iterate through elements of that stack and perform some action

Is new Stack<T>(curStack) returns reverse stack a bug?

This would appear to be a bug. Consider the following:
... then:
After doing some checking, I found this answer as to some 'reversal' in stack order.
Wouldn't it be proper to expect the second stack to be in the same order as the original?
Is this a bug?
No, it's not a bug.
A stack will yield the most recently added item first. So when you go to populate the new stack you're adding the newest item first. Since this item is added first it will now be the "oldest" item in the new stack, even though it was the "newest" item in the old stack.
The reversing is entirely expected behavior.
If you had a queue, then writing var newQueue = new Queue<T>(oldQueue); would effectively create a copy. Queues yield the oldest item first, so the oldest item in the old queue becomes the oldest item in the new queue. The same would be true of a list as well.
You seem to be under the impression that there is some sort of copy constructor, in which the stack takes another stack and makes a copy. This is untrue, it simply accepts an IEnumerable<T> as its input. For List and Queue this has the effect of taking a copy, for stacks is simply has the effect of reversing the items.
It's by design.
Notice that the constructor overload of Stack<T> that you are using expects a IEnumerable<T>. The way it works is by iterating over the IEnumarable<T> and adding the items to the Stack.
Now, you are passing another Stack<T> as parameter. The way IEnumerable<T> is expected to behave is by giving the items in the order they would come when you take them from the Stack (That is LIFO: Last-In First-Out).
So, in fact, this operations are expected to reverse the stack.

How to copy items from list to stack without using loop

I do have a Stack and a List. I need to copy all the items from list to stack without using loops i.e for, foreach.. etc.
Is there recommended way of doing it?
You can create a stack from anything that is IEnumerable
var myStack = new Stack<MyObjectType>(myList);
See MSDN: http://msdn.microsoft.com/en-us/library/76atxd68.aspx
However, the stack constructor will be using a loop internally, you just don't see it.
If you want to Pop the items in the same order as they appear in your list,
then reverse your list before you create the stack from it.
var myStack = new Stack<MyObjectType>(myList.Reverse());
new Stack<T>(myListOfT)
Alternatively (without loops)
myStack.Push(myList[0]);
myStack.Push(myList[1]);
myStack.Push(myList[2]);
myStack.Push(myList[3]);
...
It's going to get pretty tedious. What's wrong with loops?
In java 1.8 Stack has a predefined method call addAll - Item will be push on to the stack
stack.addAll(list);

Stack<> implementation in C#

I've recently been implementing a recursive directory search implementation and I'm using a Stack to track the path elements. When I used string.Join() to join the path elements, I found that they were reversed. When I debugged the method, I looked into the stack and found that the elements themselves were reversed in the Stack's internal array, ie the most recently Push()ed element was at the beginning of the internal array, and the least recently Push()ed element was at the end of the internal array. This seems ass-backward and very counter-intuitive. Can somebody please tell me why Microsoft would implement a stack in such a manner ?
I think you're mistaken.
It isn't that Stack<T>.Push internally inserts an item at the start of its internal array (it doesn't). Rather, it enumerates from the top to the bottom, as this is the manner in which one would intuitively enumerate through a stack (think of a stack of pancakes: you start at the top and work your way down).
If you look at the contents of a collection from within Visual Studio's debugger, I think it will display them to you in the order they're enumerated -- not the order they're stored internally*.
Take a look at the Stack<T>.Push method in Reflector and you'll see that the code is basically exactly what you'd expect:
// (code to check array size)
this._array[this._size++] = item;
// (code to update internal version number)
So the stack internally adds new elements onto the end of its internal array. It's the Stack<T>.Enumerator class that's got you confused, not the Stack<T> class itself.
*I don't know whether this is true in general, but it's true for Stack<T>; see Hans Passant's excellent answer for the reason why.
You had me going there for a bit, that indeed looks completely bass-ackwards. There is however something else going on. The Stack<> class has a debugger visualizer, named System_StackDebugView<>. It is an internal class, you'd have to look with Reflector to see it.
That visualizer has an Items property, that's what you look at when you expand the node in the debugger. That Items property uses Stack<>.ToArray(). Which looks like this:
public T[] ToArray()
{
T[] localArray = new T[this._size];
for (int i = 0; i < this._size; i++)
{
localArray[i] = this._array[(this._size - i) - 1];
}
return localArray;
}
Yup, backwards.
What you described is the correct implementation, as a stack is a LIFO (Last in First out) structure. Imagine it like a stack of plates, the most recently element placed into the stack is the first one removed. Have you run into a stack elsewhere that is FIFO?
FIFO would be a Queue.
Here is how the stack's push and pops methods are implemented. Notice that it is using the last index in the array, rather than the first. So there must be some other problem going on to get yours backwards.
public virtual void Push(object obj)
{
if (this._size == this._array.Length)
{
object[] destinationArray = new object[2 * this._array.Length];
Array.Copy(this._array, 0, destinationArray, 0, this._size);
this._array = destinationArray;
}
this._array[this._size++] = obj;
this._version++;
}
public virtual object Pop()
{
if (this._size == 0)
{
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_EmptyStack"));
}
this._version++;
object obj2 = this._array[--this._size];
this._array[this._size] = null;
return obj2;
}
To add to the other answers, if in the debugger you scroll down to the bottom of your Stack<>'s elements and open up Raw View->Non-Public members->_array you can see the contents of the actual internal array used to hold the items and verify that they are in the expected order.
I don't see what it matters which end they consider the top of the stack, as long as you now know which end it is. It actually makes more sense that when you 'push' something on to the stack, you're pushing it on the top (beginning) and moving the other items down...

Categories