Program 3
Program 3
Erik Cooley
2.24.2023
Program 3
Design:
Introduction:
The purpose of this project is to convert an infix expression (i.e. 5 + 6, 7 * 4) to a postfix
expression (i.e. 5 6 +, 7 4 *). This procedure is of some significance in the computing world as
postfix expressions are considerably easier for computers to process. This procedure will be
accomplished using two ADTs, linked lists and stacks.
The four challenges this project presents are the creation of linked list and stack classes,
the input of an expression by the user, the task of error-checking this expression, and the
algorithm for converting from a correct infix expression to a postfix expression. Since the
conversion algorithm is already provided in the assignment, the hardest part of creating this
program is taken care of, leaving the implementation of the classes, the error checking, user
input, and the overall structure of the program.
Functions:
1) void postfixCalc()
This function will be in the main function to run continuously until the quit keyword is
entered. It will ask the user for input and store the input in a character linked list. It will then
use function checkValidity() to check if user input is a valid infix expression. If the
expression is valid, it will be put through the conversion algorithm. The corresponding
postfix expression will then be printed. This conversion algorithm also requires four auxiliary
functions to perform various checks: greaterPrecedent(), to determine which of two
operators is of greater precedence; isOp(), to determine whether a character is an operator;
isInt(), to determine if a function is an integer; and isPar(), to determine whether a character
is a parenthesis (which isn’t entirely necessary, but it keeps things consistent).
2) bool checkValidity( LinkedList )
This function will need to check for several types of errors: unbalanced parentheses,
double integers (“55”), double operators (“++”), double parentheses (“()” or “)(“), operators
to the right of opening parentheses (“(+”), integers to the left of opening parentheses (“5)”) or
to the right of closing parentheses (“)5”), and completely invalid characters, as well as
operators at the start and end of an expression. It will iterate through the linked list infix
expression, which will be passed in as an argument in the postfix() function, and output a
Boolean indicating whether the expression passed all tests.
3) bool greaterPrecedent( char, char )
This function will take two characters as input and compare them on the basis of operator
precedence. It will then return a Boolean value indicating whether the first operator is of
greater or equal to precedence than the second.
4) bool isInt( char ), bool isPar( char ), bool isOp( char )
These functions are extremely similar in function and execution. They will take in a
character and determine whether it fits the criterion of integer, parenthesis, or operator,
respectively. These functions will likely be used in checkValidity() and postfixCalc().
Data Structures:
1) Linked List
This class will be a basic linked list class with basic operations that allow it to support a
stack class. It will also need a function to read a value at a certain index. Luckily, I already
have a linked list class coded, so I’ll use that.
2) Stack
Only the basic functions of pushing, reading, printing, checking for emptiness, and
popping are necessary for this class in this program. I also already have a stack class built on
a linked list coded, so I only need to update that a bit.
Time Estimate:
I estimate this project will take me around seven hours to complete: one hour on the isOp(),
isPar(), isInt(), and greaterPrecedent() functions, two hours for the main postfix conversion
algorithm and user input, and four hours for the integration of the error checking function and
debugging (I think this will take a long time simply because of the number of test cases I will
have to run).
Programming Log:
Total time spent – 5.5 hours.
• 2.25.2023
Spent about an hour implementing the simple Boolean check functions and adding functions I
thought I might need to my stack class ( topNode() ).
• 2.26.2023
Spent 3 ½ hours implementing postfix conversion function (sans error checking). Tried to build a
functioning validity check function, but success is elusive. I keep getting an ambiguous error
message saying double free detected in tcache 2. I think this might be due to the passing in of a
linked list. Tomorrow I’ll try converting the linked list to a simple array before passing it into the
error function.
• 2.27.2023
Spent about an hour coding. Converted the linked list to an array and finished error-checking
algorithm. Everything runs great. Added a do/while loop to the main function to run the postfix
calculator continuously until user decides to quit.
Source Code:
1. plink.h
/*
* plink.h
*
* stands for “postfix linked list.” The p is silent.
*/
#ifndef PLINK_H
#define PLINK_H
#include <iostream>
using namespace std;
class LinkedList {
private:
struct node { // list is built of nodes
node * next; // next pointer
char info; // info in this linked list is a char
};
typedef node* nodeptr;
nodeptr head; // points to start of list
int count; // size of list
public:
// constructor
LinkedList() {
head = NULL;
count = 0;
}
// destructor
~LinkedList() {
while (head != NULL) {
nodeptr tmp = head;
head = head -> next;
delete tmp;
}
}
void addNode(char); // add node to front
void addToEnd(char); // add node to back
void deleteNode(char); // del node with some info char
char firstNode(); // return first node info
void print(); // print list
bool isInList(char); //check if node with some info is in list
int Size(); // return size of list
char readAtIndex(int); // return info of node at some index
};
#endif
2. plink.cpp
/*
* plink.cpp
*
* stands for “postfix linked list”
*/
#include "plink.h"
#include <iostream>
using namespace std;
if (head != NULL) {
head = n;
} else {
head = n;
n->next = NULL;
}
}
if (head != NULL) {
while (p -> next != NULL) {
p = p->next;
}
p -> next = n;
} else {
head = n;
}
}
if (head != NULL) {
do {
if (curr -> info == x) {
if (prev != NULL) {
prev -> next = curr -> next;
} else {
head = head -> next;
}
delete curr;
count--;
break;
}
prev = curr;
curr = curr->next;
} while (curr != NULL);
}
}
while (p != NULL) {
if (p -> info == x) {
yorn = true;
}
p = p->next;
}
return yorn;
}
3. pstack.h
/*
* pstack.h
* stands for “postfix stack”
*/
#ifndef PSTACK_H
#define PSTACK_H
#include "plink.h"
using namespace std;
class Stack {
private:
// each stack is made of a linked list
LinkedList top;
public:
// destructor
~Stack();
#endif
4. pstack.cpp
/*
* pstack.cpp
* stands for “postfix stack”
*/
#include "pstack.h"
#include <iostream>
using namespace std;
/* destructor */
Stack::~Stack() {
while ( !isEmpty() ) {
int n = top.firstNode();
top.deleteNode(n);
}
}
5. postfixCalc.cpp
/* postfixCalc.cpp
* CS 121.Bolden.............g++ on Ubuntu 9.3.0...........Erik Cooley
* 2.28.23.....HP, Intel CORE i5 7th [email protected]
*
* Program takes an infix expression from the user and outputs the
* corresponding postfix expression using an algorithm which utilizes
* stacks and linked lists.
*--------------------------------------------------------------------
*/
#include <iostream>
#include "plink.h"
#include "pstack.h"
void postfixCalc();
bool isInt(char);
bool isOp(char);
bool isPar(char);
int main() {
char quit; // stores quit/continue input
do {
postfixCalc();
cout << "Press any key to quit or enter to perform another
conversion: ";
cin.get(quit);
} while (quit == '\n');
return 0;
}
return valid;
}
// conversion algorithm
infix.addToEnd(')');
opstack.push('(');
while ( !opstack.isEmpty() ) {
curr = infix.readAtIndex(counter);
if (curr == '(') {
opstack.push(curr);
} else if (isInt(curr)) {
postfix.addToEnd(curr);
} else if (curr == ')') {
char tmp;
tmp = opstack.pop();
while (tmp != '(') {
postfix.addToEnd(tmp);
tmp = opstack.pop();
}
} else if (isOp(curr)) {
while (greaterPrecedent(opstack.topNode(), curr)) {
postfix.addToEnd(opstack.pop());
}
opstack.push(curr);
}
counter++;
}
$ ./postfixCalc
Input: 3 + 4
Output: 3 4 +
Press any key to quit or enter to perform another conversion:
Input: (3 + 4)
Output: 3 4 +
Press any key to quit or enter to perform another conversion:
Input: (2 + 3) * 4
Output: 2 3 + 4 *
Press any key to quit or enter to perform another conversion:
Input: 2 + ((5) * 3)
Output: 2 5 3 * +
Press any key to quit or enter to perform another conversion:
Input: 2 * ((3 + 4 * 7) / 2 + 4)
Output: 2 3 4 7 * + 2 / 4 + *
Press any key to quit or enter to perform another conversion: q