Stack question: pop out in a pattern - algorithm

At run time I want to input two types of datatype, double and string.
One of the condition is that String should pop in the order I input, and double will pop as the usual stack behaviour, LIFO. Another condition is that the stack is limited to max size 10
E.g. one runtime example
Input Hello 1 World 2 blah blah 3 4 5
Output Hello 5 World 4 blah blah 3 2 1
My first question is how many ways is there to solve this problem?
I have solved this problem using 3 stacks, one which stores double, one which store strings, and one which is used to reverse the string order.
I need to save the pattern so the program know which order the doubles comes, thus I save the pattern to the string stack. Since the stack is limited to size 10, I will need to save the pattern in another way.
So this is how my string stack will look like after the push
Hello*
World*
blah
blah***
So when at the first read I need to make specific read in that Stack position and just extract Hello out of it. Asterisk * is left for later use when I tell the program next pop is an double.
My second question is that I wonder if there is some other more elegant solution to this problem. Since my solution will involve some string manipulation to solve this problem. And as for now I'm not actually using the pop function in the string case as it is supposed to be used. I made the solution in C++ btw.

What you're doing is fine, except that if you must use a stack, then you aren't allowed to access random locations in a stack -- you can only push/pop -- and also it's not so nice to modify the input strings and store asterisks in them.
You can solve this using only push/pop operations with 5 stacks (technically, only 4 will be used at any one time, but since they are of different types, you need to declare all 5 in your program):
stack 1: push doubles in input order
stack 2: push strings in input order
stack 3: push data types (double or string) in input order
stack 4: reverse the order of strings in stack 2
stack 5: reverse the order of data types in stack 3
Now pop one data type at a time from stack 5, if it is a double, pop from stack 1, otherwise pop from stack 5, and print the popped value.
Edit: #jleedev makes a good point that there isn't a general solution when the stack size is limited. What I've described above assumes that you're allowed to use multiple stacks and each stack can hold as many items as present in the input.

I'll ignore the stack size constraint since I think it's meaning is unclear. In addition, if you can use multiple stacks all limited to size 10, then you can simulate larger stacks by using multiple actual stacks.
So, this can be done with 2 stacks using only push/pop.
push everything onto stack A.
pop everything from A onto B.
if B.empty return
if B.top is a double goto 7
output B.top and pop it off of B
goto 3
pop all of B onto A
while A.top is not a double pop A onto B
output A.top and pop it off of A
goto 2.

Related

Parse expression with functions

This is my situation: the input is a string that contains a normal mathematical operation like 5+3*4. Functions are also possible, i.e. min(5,A*2). This string is already tokenized, and now I want to parse it using stacks (so no AST). I first used the Shunting Yard Algorithm, but here my main problem arise:
Suppose you have this (tokenized) string: min(1,2,3,+) which is obviously invalid syntax. However, SYA turns this into the output stack 1 2 3 + min(, and hopefully you see the problem coming. When parsing from left to right, it sees the + first, calculating 2+3=5, and then calculating min(1,5), which results in 1. Thus, my algorithm says this expression is completely fine, while it should throw a syntax error (or something similar).
What is the best way to prevent things like this? Add a special delimiter (such as the comma), use a different algorithm, or what?
In order to prevent this issue, you might have to keep track of the stack depth. The way I would do this (and I'm not sure it is the "best" way) is with another stack.
The new stack follows these rules:
When an open parentheses, (, or function is parsed, push a 0.
Do this in case of nested functions
When a closing parentheses, ), is parsed, pop the last item off and add it to the new last value on the stack.
The number that just got popped off is how many values were returned by the function. You probably want this to always be 1.
When a comma or similar delimiter is parsed, pop from the stack, add that number to the new last element, then push a 0.
Reset so that we can begin verifying the next argument of a function
The value that just got popped off is how many values were returned by the statement. You probably want this to always be 1.
When a number is pushed to the output, increment the top element of this stack.
This is how many values are available in the output. Numbers increase the number of values. Binary operators need to have at least 2.
When a binary operator is pushed to the output, decrement the top element
A binary operator takes 2 values and outputs 1, thus reducing the overall number of values left on the output by 1.
In general, an n-ary operator that takes n values and returns m values should add (m-n) to the top element.
If this value ever becomes negative, throw an error!
This will find that the last argument in your example, which just contains a +, will decrement the top of the stack to -1, automatically throwing an error.
But then you might notice that a final argument in your example of, say, 3+ would return a zero, which is not negative. In this case, you would throw an error in one of the steps where "you probably want this to always be 1."

dc: how do I pop (and discard) the top number of the stack?

In dc, how do I pop and discard a number from the top of the stack? A stack with three items (1 2 3) should become a stack with two items (2 3). Currently I'm shoving the number onto another stack (Sz) but that seems rather lame.
There are numerous ways to delete the top of the stack but they have side effects. Removing an element without side effects requires you to avoid included side effects.
To remove the top of the stack without a side effect, ensure that the top is a number and then run d!=z. If the stack had [5], this does the following
Start with item to remove. Stack: [5]
Duplicate top of stack. Stack: [5,5]
Pop top 2 and test if they are not equal: 5 != 5 Stack: []
If test passed (which it can't), run z Stack: []
To ensure that the top of stack is a number, I use Z which will calculate the length of a string or the number of digits in a number and push that back. There are other options such as X. Anything that makes a number out of anything will work so that it will be compatible with !=.
So the full answer for copy pasting in all situations is the following:
Zd!=r
I usually stick this in register D (for Drop):
[Zd!=r]sD
and then I can run
lDx

How does the stack work?

I have a couple questions about the stack. One thing I don't understand about the stack is the "pop" and "push" idea. Say I have integers a and b, with a above b on the stack. To access b, as I understand it, a would have to be popped off the stack to access b. So where is "a" stored when it is popped off the stack.
Also if stack memory is more efficient to access than heap memory, why isn't heap memory structured like the stack? Thanks.
So where is "a" stored when it is popped off the stack.
It depends. It goes where the program that's reading the stack decides. It may store the value, ignore it, print it, anything.
Also if stack memory is more efficient to access than heap memory, why
isn't heap memory structured like the stack?
A stack isn't more efficient to access than a heap is, it depends on the usage. The program's flow gets deeper and shallower just like a stack does. Local variables, arguments and return addresses are, in mainstream languages, stored in a stack structure because this kind of structure implements more easily the semantics of what we call a function's stack frame. A function can very efficiently access its own stack frame, but not necessarily its caller functions' stack frames, that is, the whole stack.
On the other hand, the heap would be inefficient if it were implemented that way, because it's expected for the heap to be able to access and possibly delete items anywhere, not just from its top/bottom.
I'm not an expert, but you can sort of think of this like the Tower of Hanoi puzzle. To access a lower disc, you "pop" discs above it and place them elsewhere - in this case, on other stacks, but in the case of programming it could be just a simple variable or pointer or anything. When you've got the item you need, then the other ones can be put back on the stack or moved elsewhere entirely.
Lets take your case scenario .
You have a stack with n elements on it, the last one is a, b is underneath.
pop operation returns the popped value, so if you want to access the second from the top being b, you could do:
var temp = stack.pop()
var b = stack.pop()
stack.push(temp)
However, stack would rarely be used this way. It is a LIFO queue and works best when accessed like a LIFO queue.
It seems you would rather need a collection with a random index based access.
That collection would probably be stored on the heap. Hope it clarified stack pop/push a little.
a is stored wherever you decide to store it. :-) You need to provide a variable in which to store the value at the top of the stack (a) when you remove it, then remove the next item (b) and store it in a different variable to use it, and then push the first value (a) back on the stack.
Picture an actual pile of dirty plates sitting on your counter to your left. You pick one up to wash it (pop it from the "dirty" stack), wash it, dry it, and put it on the top of the clean stack (push it) on your right.
If you want to reach the second plate from the top in either stack, you have to move the top one to get to it. So you pick it up (pop it), put it somewhere temporarily, pick up the next plate (pop it) and put it somewhere, and then put the first one you removed back on the pile (push it back on the stack).
If you can't picture it with plates, use an actual deck of playing cards (or baseball cards, or a stack of paper - anything you can neatly pile ("stack")) and put it on your desk at your left hand. Then perform the steps in my last paragraph, replacing the word "plate" with "card" and physically performing the steps.
So to access b, you declare a variable to store a in, pop a and save it in that variable, pop b into it's own variable, and then push a back onto the stack.

Prefix to Infix Conversion Algorithm with figure

After some google search I find it!
Prefix to Infix
This algorithm is a non-tail recursive method.
The reversed input string is completely pushed into a stack.
prefixToInfix(stack)
1) IF stack is not empty
a. Temp -->pop the stack
b. IF temp is a operator
i. Write a opening parenthesis to output
ii. prefixToInfix(stack)
iii. Write temp to output
iv. prefixToInfix(stack)
v. Write a closing parenthesis to output
c. ELSE IF temp is a space -->prefixToInfix(stack)
d. ELSE
i. Write temp to output
ii. IF stack.top NOT EQUAL to space -->prefixToInfix(stack)
when the Stack top is
F(ABC)
and we enter the algorithm, "A" is written to the output as it was currently the value of
temp=A (say)
Now how I get '-' on the output column as according to the algorithm the next temp value will be "B" which was popped from the stack after the last recursive call.
How the diagram is showing output "((A-" ...
Where I am doing the incorrect assumption ?
Could someone take the trouble in explaining it ?
I don't quite understand your question.
If your stack is ABC, F(ABC) pops the A, goes into branch d.i. and writes an A to output, goes on into d.ii. and performs F(BC), which will, in the end, write both the B and C to output.
If you want your output to look like it does on the diagram, you'll need your stack to be * - A B C (note the spaces between every element!).
Edit:
(As an aside: all this is easier stepped through than described, so I suggest you write the algorithm as a program and start it in your choice of debugger.)
OK, so you have stored the first * in temp (a), written a ( (b.i.), and called the algorithm with the remaining stack (b.ii.). This throws away a blank, then you store a - in the next branch's temp, write a (, and called the algorithm with the remaining stack. At some point, you end up in d.ii., you have just written an A to output, giving you
((A
and the remaining stack is
_B_C
with a space on top and another space between B and C.
So now d.ii. finds the space and doesn't do anything anymore: this control branch is done, and we go back to where we came from, which was d.ii. in your - control branch. You write the - to output at d.iii., call the algorithm with the remaining stack (_B_C) at d.iv., and there you go, writing the B, a ), the * and C and the last ).
Just remember where you came from, so you know where to jump back after your current recursion is done.

Calculator stack

My understanding of calculators is that they are stack-based. When you use most calculators, if you type 1 + 2 [enter] [enter] you get 5. 1 is pushed on the stack, + is the operator, then 2 is pushed on the stack. The 1st [enter] should pop 1 and 2 off the stack, add them to get 3 then push 3 back on the stack. The 2nd [enter] shouldn't have access to the 2 because it effectively doesn't exist anywhere.
How is the 2 retained so that the 2nd [enter] can use it?
Is 2 pushed back onto the stack before the 3 or is it retained somewhere else for later use? If it is pushed back on the stack, can you conceivably cause a stack overflow by repeatedly doing [operator] [number] [enter] [enter]?
Conceptually, in hardware these values are put into registers. In simple ALU (Arithmatic Logical Units (i.e. simply CPUs)), one of the registers would be considered an accumulator. The values you're discussing could be put on a stack to process, but once the stack is empty, the register value (including the last operation) may be cached in these registers. To which, when told to perform the operation again, uses the accumulator as well as the last argument.
For example,
Reg1 Reg2 (Accumulator) Operator
Input 1 1
Input + 1 +
Input 2 2 1 +
Enter 2 3 +
Enter 2 5 +
Enter 2 7 +
So it may be a function of the hardware being used.
The only true stack based calculators are calculators which have Reverse Polish Notation as the input method, as that notation directly operates on stacks.
All you would need to do is retain the last operator and operand, and just apply them if the stack is empty.
There is an excellent description and tutorial of the Shunting-yard algorithm (infix -> rpn conversion) on wikipedia.

Resources