Stacks and Templates
This assignment is a calculator that is actually made up of two programs,
a infix to postfix converter and a postfix calculator.
The algorithms for both programs are stack based,
so you will use a templated stack to solve for both.
Postfix Arithmetic
The normal notation you use is actually "infix" notation, this
indicates that the operator is listed between the operands. For
"postfix" arithmetic, the operator is after the operands.
Here are some examples :
Infix Postfix
2 + 3 2 3 +
2 + 3 * 5 2 3 5 * +
(2 + 3) * 5 2 3 + 5 *
2 / 3 - 5 * 7 2 3 / 5 7 * -
The Templated Stack
Start off with a simple integer stack, and test it
before you template it.
Then template your stack, and test it again
to see if you goofed anything up.
Remember since it is templated you need the implementation in the
header file so the type binding can be done correctly.
However all non-templated classes need to have a separate cpp and header file.
The Infix to Postfix Converter
You are making a program that will take an infix math expression
and output the postfix for it. This will need a stack of characters.
Here is the algorithm.
- Push a '(' onto the stack.
- Until you reach end of file,
read input from the infix expression and do the following :
- If it is a number, output the number followed by a space.
- If it is a '(', place it on the stack.
- If it is a ')', pop and output the operators until a '(' is
found. Then discard the both '(' and ')'.
- If it is an operator, pop and output any operators on the top
of the stack that are of greater or equal precedence, then place the new
operator on the stack.
- Treat it like you just read a ')' as input ( Repeat the code you
wrote for ')', but do it after the input loop. ).
This needs to have the following features.
- It must read until end of file. ( eof is control-d )
- The ability to deal with multi-digit integers as input.
- The operators are + - * / ^
If it had any output that was not the result it should be output to
stderr not stdout ( use cerr instead of cout ). The result needs to
go to stdout so it will pipe correctly.
The Postfix Calculator
Write a program that can read in a postfix expression and output the result.
This will need a stack of floats.
Here is the logic:
- If the input is a number push it onto the stack.
- If the input is an operator, pop top two numbers and apply the
operator.
Note: The first number off the stack is the right hand side of
the operation. The result is then pushed on the stack.
For this calculator we need to support + - / * ^.
Note: the exponentiation operation (^) can't be executed with that operator,
( it is the bitwise operator XOR )
you will need to call the powf( the float version of pow ) function.
This needs to have the following features.
- It must read until end of file. ( eof is control-d )
- The ability to deal with multi-digit integers as input.
- It must support these operators + - * / ^
- generate the result as a floating point.
Input handling
You will want to use functions like
isdigit( int ), cin.putback( char ),
and get the input a character at a time,
( this will help with the multi-digit numbers ) .
This will allow you to test the input char using isdigit,
if it is put it back in the input stream,
and read in the data as an numeric type.
All cin.putback( char ) does is place the char back in the input stream,
just as if it had never been read.
Here is the code to do this :
char ch;
int num;
while( cin >> ch )
{
if ( isdigit( ch ) )
{
cin.putback( ch );
cin >> num;
The Finished product
You can input a valid infix expression into the infix to postfix
converter, and pipe its output to this postfix calculator
program and get the result of the infix expression. So you get three
programs for the price of two. Each run of the program(s) only
handles one expression.
If your programs are named convert and calc this will run them together
using a pipe.
./convert | ./calc
Note: If your converter program outputs anything other than the postfix
expression you need to either send it to stderr or have your calculator
handle the input correctly without failing. Only data sent to stdout will
go over the pipe.
Here are some example runs from mine :
[jclark@arioch calc]$ echo "2 + 3 * 5" | ./convert
2 3 5 * +
[jclark@arioch calc]$ echo "2 + 3 * 5" | ./convert | ./calc
17
[jclark@arioch calc]$ printf "2\n + 3 \n* 5" | ./convert | ./calc
17
[jclark@arioch calc]$ echo "( 2 + 3 ) * 5 / 4" | ./convert
2 3 + 5 * 4 /
[jclark@arioch calc]$ echo "( 2 + 3 ) * 5 / 4" | ./convert | ./calc
6.25
[jclark@arioch calc]$ echo "2/0" | ./convert
2 0 /
[jclark@arioch calc]$ echo "2/0" | ./convert | ./calc
can't divide by zero
[jclark@arioch calc]$ echo "12 - 158 / 16" | ./convert
12 158 16 / -
[jclark@arioch calc]$ echo "12 - 158 / 16" | ./convert | ./calc
2.125
Program Requirements
- The stack needs to be dynamic.
- The converter only needs to read in non-negative integers.
- The input for both programs must be able to deal with
whitespace ( or no whitespace ).
- Both programs need to read until end of file ( from stdin ).
When typing on a keyboard eof is control-d.
This is due on July 22nd.
These programs are worth 200 points.
Your Makefile needs to build both programs by default.
The Goals
- write and template a stack class
- solve simple stack problems using your templated stack
- use pipes to solve complex problems