CS1101C Lab 4 (Even Week)

Postfix Stack Arithmetic

The deadline for this lab question is Friday 09 November 2007, 23:59:59 hours.

The name of your C program file must be called postfix.c, files with any other name will not be marked.

Preliminary

This lab comprises two parts. In the former, you are tasked to implement a stack data structure using arrays, while in the latter you will make use of the stack to evaluate postfix arithmetic expressions.

Stack Data Structure

We have learned that arrays can be used to organize a collection of homogeneous data items into a sequence where particular items can be accessed through indexing (or subscripting) of an array. A stack is another data structure for organizing homogeneous data. In particular, a stack is a last-in-first-out (LIFO) data structure; a good example is the stack of trays you see in front of the food stalls in the canteen. Every sane person will remove a tray from the top of the stack (you can try taking from the bottom... but don't mention that you got the idea from me...). Before a stack finishes, a canteen attendant might replenish the stack by putting the trays on the top. So the effect is that trays at the bottom are always relatively new and unused.

There are two main operations for the stack, namely push and pop. We can push an item to the top of the stack; this is like placing a tray on the top of the stack of trays. We can also pop an item from the top of the stack; this is like taking the top tray from the top of the stack of trays. In this lab, you will realize a stack for storing integers. Since there is no stack data structure readily available, we shall implement one using an array. The details of the implementation is left to the individual student. You can design the stack in anyway you wish, as long as you adhere to the specifications of the following four functions.

int isEmpty(int stack[]);

The above function returns zero if stack is empty, else a non-zero number is returned.

void printStack(int stack[]);

The function prints out the items of stack as a list starting from the topmost item as shown below:
{ [top item] [next item] ... [bottom item] }
If stack is empty, then an empty list is printed.
{ }
See the sample output below for more details.

void pushStack(int stack[], int item);

The above function "pushes" an item onto the top of stack. For simplicity, assume that the stack can take a maximum of 100 items, and that we never overflow the stack with more than 100 items.

int popStack(int stack[]);

The above function first checks if stack is empty. If it is, then the constant EMPTY is returned. We define the constant EMPTY as the smallest integer value as shown below.
#include <limits.h>

#define EMPTY INT_MIN
Otherwise, if stack is not empty, the top item is "popped" out of the stack and returned.

Testing your functions

You should test that the above functions work before carrying on to the next part. A sample main method is given below.

#include <stdio.h>
#include <limits.h>

#define MAX 100
#define EMPTY INT_MIN

/* Function prototypes and function definitions skipped... */

int main(void)
{
   //Declare your stack array.

   printf("\nPrint the initial stack...\n");
   printStack(stack);

   printf("\nPush 50 onto the stack...\n");
   pushStack(stack,50);
   printStack(stack);

   printf("\nPush -60 onto the stack...\n");
   pushStack(stack,-60);
   printStack(stack);

   printf("\nPop from the stack...%d\n", popStack(stack));
   printStack(stack);

   printf("\nPush 70 onto the stack...\n");
   pushStack(stack,70);
   printStack(stack);

   printf("\nPop from the stack...%d\n", popStack(stack));
   printStack(stack);

   printf("\nPop from the stack...%d\n", popStack(stack));
   printStack(stack);

   printf("\nPop from the stack...%d\n", popStack(stack));
   printStack(stack);
}

The output of the above main function is given below.

Print the initial stack...
{ }

Push 50 onto the stack...
{ [50] }

Push -60 onto the stack...
{ [-60] [50] }

Pop from the stack...-60
{ [50] }

Push 70 onto the stack...
{ [70] [50] }

Pop from the stack...70
{ [50] }

Pop from the stack...50
{ }

Pop from the stack...-2147483648
{ }

Postfix Expression Evaluation

It is very common to write mathematical expressions as infix expressions where parentheses are vital to ensure the ordering of various operations. Examples of infix expressions are 4*3 and (4*3)+(5-2). However, parenthesis can be removed if we rewrite the above using postfix expressions. For the above example, the postfix expressions are 4 3 * and 4 3 * 5 2 - + respectively. Here you will need to use your deductive and inference skills again to determine how valid postfix expressions can be written.

Postfix expression evaluation can be implemented using a stack. An example is given for the expression 4 3 * 5 2 - +.

  1. Push 4 onto the stack.
    Stack contents: { [4] }
  2. Push 3 onto the stack.
    Stack contents: { [3] [4] }
  3. Since * involves two operands, pop the top two values out of the stack, perform the multiplication and push the result 12 onto the stack.
    Stack contents: { [12] }
  4. Push 5 onto the stack.
    Stack contents: { [5] [12] }
  5. Push 2 onto the stack.
    Stack contents: { [2] [5] [12] }
  6. Since - involves two operands, pop the top two values out of the stack, perform the subtraction and push the result 3 onto the stack.
    Stack contents: { [3] [12] }
  7. Since + involves two operands, pop the top two values out of the stack, perform the addition and push the result 15 onto the stack.
    Stack contents: { [15] }
The single value remaining on the stack after the postfix expression evaluation will be the result.

Your task is to write a function postfix that takes in a stack data structure and a character string containing the expression to be evaluated and return the answer. The prototype of the postfix function is given below

int postfix(int stack[], char *str);
or
int postfix(int stack[], char str[]);
The user will be asked for a postfix expression involving the following operands: Note that all of the above (except unary minus) take in two operands, while the unary minus only takes in one operand, e.g. 5~ to denote the negative integer -5. To make life simple, all integral values that make up an infix expression are single digit. So in order to evaluate -42/-5, we need to provide the postfix expression 8 5 * 2 + ~ 5 ~ / which means -((8*5)+2)/(-5) in infix form. And since every single digit in the postfix expression represents an integer value, we can then remove all the spaces from the postfix expression and equivalently write 85*2+~5~/.

The following main method is provided for you in which the user will repeatedly enter a postfix expression (a valid expression can include blank spaces) for evaluation. The program terminates only if the user enters an expression starting with a 'q' or 'Q'. Do not modify the main method.

int main(void)
{
   //Declare your stack array.
   char str[100] = {'\0'};

   printf("Enter a postfix expression: ");
   fgets(str, 100, stdin);
   while (tolower(*str) != 'q')  // uses ctype function tolower
   {
      printf("The answer is %d.\n\n", postfix(stack,str));
      printf("Enter a postfix expression: ");
      fgets(str, 100, stdin);
   }

   return 0;
}

Sample Run

A sample run of the program is as follows.

$ gcc -Wall postfix.c -o postfix
$ ./postfix
Enter a postfix expression: 43*
The answer is 12.

Enter a postfix expression: 4 3 * 5 2 - +
The answer is 15.

Enter a postfix expression: 43*         52 -+
The answer is 15.

Enter a postfix expression: 8 5 * 2 + ~ 5 ~ /
The answer is 8.

Enter a postfix expression: 85*2+~5~/
The answer is 8.

Enter a postfix expression: 96%2%
The answer is 1.

Enter a postfix expression: Quit.

$

Note and Ponder

  1. Assume that all user input is valid. No error checking is required.

  2. Assume that division by zero error will not occur.

  3. To print the % symbol, use the %% format specifier in your printf statement.

  4. If your program does not work as you expect (logical errors), use extra printf statements to print out all the values of your variables to aid in your debugging.

  5. Most importantly, have lots of fun programming!


This document, index.html, has been accessed 37 times since 25-Jun-24 11:57:13 +08. This is the 1st time it has been accessed today.

A total of 27 different hosts have accessed this document in the last 445 days; your host, nsrp-source.comp.nus.edu.sg, has accessed it 8 times.

If you're interested, complete statistics for this document are also available, including breakdowns by top-level domain, host name, and date.