Understand the stack ADT and its applications. Understand infix to postfix conversion and postfix expression evaluation.
Implement a generic stack container as an adaptor class template. Implement a program that converts infix expression to postfix expression and implement a program that evaluates postfix expression using the stack container you develop.
A Stack is a type of data container/ data structure that implements the LAST-IN-FIRST-OUT (LIFO) strategy for inserting and recovering data. This is a very useful strategy, related to many types of natural programming tasks as we have discussed.
Remember that in the generic programming paradigm, every data structure is supposed to provide encapsulation of the data collection, enabling the programmer to interact with the entire data structure in a meaningful way as a container of data. By freeing the programmer from having to know its implementation details and only exporting the interface of its efficient operations, a generic Stack provides separation of data access/manipulation from internal data representation. Programs that access the generic Stack only through the interface can be re- used with any other Stack implementation. This results in modular programs with clear functionality and that are more manageable.
Goals:
More detailed descriptions for each of the above tasks are now provided.
Task1: Implement Stack adaptor class template
Interface:
The interface of the Stack class template is specified below.
The following non-member functions should also be supported.
Analyze the worst-case run-time complexity of the member function clear() of Stack. Give the complexity in the form of Big-O. Your analysis can be informal; however, it must be clearly understandable by others. Note that the time complexity of the function clear() depends on the underlying adaptee class you use for the implementation of Stack. Name the file containing the complexity analysis as "analysis.txt", in which, you should state the time complexity of clear() in the Big-O notation, your discussions on why it is so, in particular, you need to include the information on the underlying adaptee class you used in the implementation of the Stack.
Task 2:
Convert infix arithmetic expressions into postfix arithmetic expressions and evaluate them (whenever possible)
For the sake of this, an arithmetic expression is a sequence of space-separated strings. Each string can represent an operand, an operator, or parentheses.
Operands: can be either a numerical value or a variable. A variable name only consists of alphanumerical letters and the underscore letter "_". A variable name starts with a English letter. Numerical operands can be either integer or floating point values.
Examples of operands: "34", "5", "5.3", "a", "ab", "b1", and "a_1"
Operators: one of the characters '+', '-', '*', or '/'. As usual, '*' and '/' are regarded as having higher precedence than '+' or '-'. Note that all supported operators are binary, that is, they require two operands.
Parentheses: '(' or ')'
An Infix arithmetic expression is the most common form of arithmetic expression used.
Examples:
( 5 + 3 ) * 12 - 7 is an infix arithmetic expression that evaluates to 89
5 + 3 * 12 - 7 is an infix arithmetic expression that evaluates to 34
For the sake of comparison, postfix arithmetic expressions (also known as reverse Polish notation) equivalent to the above examples are:
5 3 + 12 * 7 -
5 3 12 * + 7 -
Two characteristics of the Postfix notation are (1) any operator, such as '+' or '/' is applied to the two prior operand values, and (2) it does not require the use of parenthesis.
More examples:
a + b1 * c + ( dd * e + f ) * G in Infix notation becomes
a b1 c * + dd e * f + G * + in Postfix notation
To implement infix to postfix conversion with a stack, one parses the expression as sequence of space-separated strings. When an operand is read in the input, it is immediately output. Operators (e.g., '-', '*') may have to be saved by placement in an operator stack. We also stack left parentheses. Start with an initially empty operator stack.
Follow these 4 rules for processing operators/parentheses:
Evaluating postfix arithmetic expressions
After converting a given expression in infix notation to postfix notation, you will evaluate the resulting arithmetic expression IF all the operands are numeric (int, float, etc.) values. Otherwise, if the resulting postfix expression contains characters, your output should be the same as the input (the postfix expression).
Example inputs:
5 3 + 12 * 7 -
5 3 12 * + 7 -
3 5 * c - 10 /
Example outputs:
89
34
3 5 * c - 10 /
To achieve this, you will have an operand stack, initially empty. Assume that the expression contains only numeric operands (no variable names). Operands are pushed into the stack as they are ready from the input. When an operator is read from the input, remove the two values on the top of the stack, apply the operator to them, and push the result onto the stack. If an operator is read and the stack has fewer than two elements in it, report an error. If end of input is reached and the stack has more than one operand left in it, report an error. If end of input is reached and the stack has exactly one operand in it, print that as the final result, or 0 if the stack is empty.
Summarizing task 2.
Your program should expect as input from (possibly re-directed) stdin a series of space-separated strings. If you read a1 (no space) this is the name of the variable a1 and not "a" followed by "1". Similarly, if you read "bb 12", this is a variable "bb" followed by the number "12" and not "b" ,"b", "12" or "bb", "1" ,"2". The resulting postfix expression should be printed to stdout.
Your program should evaluate the computed postfix expressions that contain only numeric operands, using the above algorithm, and print the results to stdout.
Restrictions
The infix to postfix conversion MUST be able to convert expressions containing both numbers and variable names.
Your program MUST be able to produce floating number evaluation (i.e., deal with floats correctly).
Your program MUST NOT attempt to evaluate postfix expressions containing variable names. It should print the postfix-converted result to stdout and MAY NOT throw an exception nor reach a runtime error in that case.
Your program MUST check for mismatched parentheses (this should be taken care of if you infix to postifx expression conversion is performed properly.
Your program MUST check invalid infix expressions and report errors. We consider the following types of infix expressions as invalid expressions: 1) an operator does not have the corresponding operands, 2) an operand does not have the corresponding operator; or ) mismatched parentheses. Note that some checks can be performed in the expression conversion or postfix evaluation.
Your program MUST re-prompt the user for the next infix expression. Your program must be able to process several inputs before terminating.
Deliverable Requirements
Your implementation should be contained in three files, which MUST be named makefile, stack.h, stack.hpp and in2post.cpp. Including the three files (stack.h, stack.hpp, and in2post.cpp), the makefile you use, and the analysis.txt file for time complexity of the clear() function of Stack.