3.19 Rewrite the List class without using header an tail nodes and describe the differences between the class and the class provided in Section 3.5
3.21 Write a program to check for balancing symbols: (/**/,(),[],{})
3.22 Write a program to evaluate a postfix expression.
3.23 a. Write a program to convert an infix expression that includes (, ), +, -, * and / to postfix.
b. Add the exporientiation operator to your repertoire.
c. Write a program to convert a postfix expression to infix.
//3.19 list.hpp
#ifndef LIST_HPP__
#define LIST_HPP__
#include <iosfwd>
template< typename Object >
class List {
private:
class Node {
public:
Node(const Object& val = Object(), Node* n = 0, Node* p = 0)
: next(n), prev(p), data(val){}
public:
Node* next;
Node* prev;
Object data;
};
public:
List() : theSize(0), head(0), tail(0) {}
~List()
{
clear();
}
bool empty() const { return theSize == 0; }
const int size() const { return theSize; }
void push_back(const Object& val)
{
if(empty())
{
Node* newnode = new Node(val);
head = newnode;
tail = newnode;
++theSize;
}
else
{
Node* newnode = new Node(val, 0, tail);
tail->next = newnode;
tail = newnode;
++theSize;
}
}
void pop_back()
{
if(empty())
return;
Node* p = tail;
tail = tail->prev;
tail->next = 0;
delete p;
--theSize;
}
void push_front(const Object& val)
{
if(empty())
{
Node* newnode = new Node(val);
head = newnode;
tail = newnode;
++theSize;
}
else
{
Node* newnode = new Node(val,head,0);
head->prev = newnode;
head = newnode;
++theSize;
}
}
void pop_front()
{
if(empty())
return;
Node* p = head;
head = head->next;
head->prev = 0;
delete p;
--theSize;
}
void clear()
{
while(!empty())
{
if(head == tail)
{
delete head;
--theSize;
}
else
{
pop_back();
}
}
}
void print(std::ostream& out)
{
if(empty())
return;
Node* p = head;
while(p->next != 0)
{
out << p->data << "/n";
p = p->next;
}
out << p->data << "/n";
}
private:
List(const List&);
List& operator=(const List&);
Node* head;
Node* tail;
int theSize;
};
#endif
//3.21 stack.hpp
#ifndef STACK_HPP__
#define STACK_HPP__
template< typename Object >
class Stack {
public:
Stack(const int size = 0)
{ init(size); }
const int size() const { return theSize; }
bool empty() const { return theSize == 0; }
const int capacity() const { return theCapacity; }
void push(const Object& val)
{
if(theSize == theCapacity)
reserve(2 * theCapacity + 1);
objects[theSize++] = val;
}
void pop()
{
if(theSize > 0)
--theSize;
}
Object top()
{
return objects[size() - 1];
}
private:
void resize(const int newSize)
{
if(newSize > theCapacity)
reserve(newSize * 2 + 1);
theSize = newSize;
}
void reserve(const int newCapacity)
{
if(newCapacity < theSize)
return;
Object* old = objects;
objects = new Object[newCapacity];
for(int i = 0; i < theSize; ++i)
objects[i] = old[i];
theCapacity = newCapacity;
delete[] old;
}
void init(const int size)
{
objects = new Object[size + SPARE_CAPACITY];
theSize = 0;
theCapacity = size + SPARE_CAPACITY;
}
Stack(const Stack&);
Stack& operator=(const Stack&);
Object* objects;
int theSize;
int theCapacity;
enum { SPARE_CAPACITY = 16 };
};
#endif
//main.cpp
#include "stack.hpp"
#include <iostream>
#include <string>
using namespace std;
void testPair()
{
Stack<string> stack;
string s(""), expected("");
while(s != "e" && s != "E")
{
cout << "Enter symbols to test, e to end: /n";
cin >> s;
if(s == expected)
{
stack.pop();
if(!stack.empty())
{
string temp = stack.top();
if(temp == "(")
{
expected = ")";
}
else if(temp == "[")
{
expected = "]";
}
else if(temp == "{")
{
expected = "}";
}
else if(temp == "/*")
{
expected = "*/";
}
}
}
else if(s != "e" && s != "E")
{
if(s == "(")
{
stack.push(s);
expected = ")";
}
else if(s == "[")
{
stack.push(s);
expected = "]";
}
else if(s == "{")
{
stack.push(s);
expected = "}";
}
else if(s == "/*")
{
stack.push(s);
expected = "*/";
}
else
{
expected = "";
}
}
else
break;
}
if( stack.empty() )
{
cout << "You entered symbol form pairs/n";
}
else
{
cout << "The symbols you entered do not form pairs/n";
}
}
int main()
{
while(true)
testPair();
return 0;
}
//3.22 stack.hpp
#ifndef STACK_HPP__
#define STACK_HPP__
template< typename Object >
class Stack {
public:
Stack(const int size = 0)
{ init(size); }
const int size() const { return theSize; }
bool empty() const { return theSize == 0; }
const int capacity() const { return theCapacity; }
void push(const Object& val)
{
if(theSize == theCapacity)
reserve(2 * theCapacity + 1);
objects[theSize++] = val;
}
void pop()
{
if(theSize > 0)
--theSize;
}
Object top()
{
return objects[size() - 1];
}
private:
void resize(const int newSize)
{
if(newSize > theCapacity)
reserve(newSize * 2 + 1);
theSize = newSize;
}
void reserve(const int newCapacity)
{
if(newCapacity < theSize)
return;
Object* old = objects;
objects = new Object[newCapacity];
for(int i = 0; i < theSize; ++i)
objects[i] = old[i];
theCapacity = newCapacity;
delete[] old;
}
void init(const int size)
{
objects = new Object[size + SPARE_CAPACITY];
theSize = 0;
theCapacity = size + SPARE_CAPACITY;
}
Stack(const Stack&);
Stack& operator=(const Stack&);
Object* objects;
int theSize;
int theCapacity;
enum { SPARE_CAPACITY = 16 };
};
#endif
//main.cpp
#include "stack.hpp"
#include <iostream>
#include <cstdlib>
#include <string>
using namespace std;
int parsePostfixExp(string input)
{
Stack<int> stack;
for(size_t i = 0; i < input.length(); ++i)
{
if(input[i] != '+' && input[i] != '-' && input[i] != '*' && input[i] != '/')
{
char temp[] = {input.at(i)};
stack.push(atoi(temp));
}
else
{
int num1, num2;
num1 = stack.top();
stack.pop();
num2 = stack.top();
stack.pop();
switch(input[i])
{
case '+':
stack.push(num2 + num1);
break;
case '-':
stack.push(num2 - num1);
break;
case '*':
stack.push(num2 * num1);
break;
case '/':
stack.push(num2 / num1);
break;
default:
break;
}
}
}
if(stack.size() == 1)
{ return stack.top(); }
else
{ return -1; }
}
int main()
{
string input;
cin >> input;
cout << parsePostfixExp(input);
return 0;
}
//3.23 stack.hpp
#ifndef STACK_HPP__
#define STACK_HPP__
template< typename Object >
class Stack {
public:
Stack(const int size = 0)
{ init(size); }
const int size() const { return theSize; }
bool empty() const { return theSize == 0; }
const int capacity() const { return theCapacity; }
void push(const Object& val)
{
if(theSize == theCapacity)
reserve(2 * theCapacity + 1);
objects[theSize++] = val;
}
void pop()
{
if(theSize > 0)
--theSize;
}
Object top()
{
if(!empty())
return objects[size() - 1];
return Object();
}
private:
void resize(const int newSize)
{
if(newSize > theCapacity)
reserve(newSize * 2 + 1);
theSize = newSize;
}
void reserve(const int newCapacity)
{
if(newCapacity < theSize)
return;
Object* old = objects;
objects = new Object[newCapacity];
for(int i = 0; i < theSize; ++i)
objects[i] = old[i];
theCapacity = newCapacity;
delete[] old;
}
void init(const int size)
{
objects = new Object[size + SPARE_CAPACITY];
theSize = 0;
theCapacity = size + SPARE_CAPACITY;
}
Stack(const Stack&);
Stack& operator=(const Stack&);
Object* objects;
int theSize;
int theCapacity;
enum { SPARE_CAPACITY = 16 };
};
#endif
//infix to postfix itopconvert.hpp
#include "stack.hpp"
#include <string>
std::string infixToPostfix(const std::string& input)
{
std::string retVal;
enum priority{ UNUSE = -2, LOWEST = -1, LOW = 0, MID = 1, HIGH = 2, HIGHER = 3, HIGHEST = 4};
struct Symbol {
char symbol;
priority pri;
bool parFlag;
};
Stack<Symbol> stack;
Symbol item;
for(size_t i = 0; i < input.length(); ++i)
{
int data = input.at(i);
if(data != '+' && data != '-' && data != '*' && data != '/'
&& data != '(' && data != ')' && data != '^')
{
retVal.push_back(data);
}
else
{
switch(data)
{
case '+':
item.symbol = '+';
item.parFlag = false;
item.pri = LOW;
break;
case '-':
item.symbol = '-';
item.parFlag = false;
item.pri = LOW;
break;
case '*':
item.symbol = '*';
item.pri = MID;
item.parFlag = false;
break;
case '/':
item.symbol = '/';
item.parFlag = false;
item.pri = MID;
break;
case '(':
item.symbol = '(';
item.parFlag = true;
item.pri = HIGHEST;
break;
case ')':
item.symbol = ')';
item.parFlag = false;
item.pri = LOWEST;
break;
case '^':
item.symbol = '^';
item.parFlag = false;
item.pri = HIGHER;
break;
default:
break;
}
if(stack.empty() || stack.top().pri < item.pri || stack.top().parFlag == true)
{
stack.push(item);
}
else if(item.symbol == ')')
{
while(stack.top().symbol != '(')
{
retVal.push_back(stack.top().symbol);
stack.pop();
}
stack.pop();
}
else if(stack.top().pri >= item.pri)
{
while(!stack.empty() && stack.top().pri >= item.pri && stack.top().symbol != '(')
{
retVal.push_back(stack.top().symbol);
stack.pop();
}
stack.push(item);
}
}
}
while(!stack.empty())
{
retVal.push_back(stack.top().symbol);
stack.pop();
}
return retVal;
}
//postfix to infix ptoiconvert.hpp
#ifndef PTOICONVERT_HPP__
#define PTOICONVERT_HPP__
#include <string>
std::string postfixToInfix(std::string input)
{
Stack<std::string> stack;
for(size_t i = 0; i < input.length(); ++i)
{
if(input[i] != '+' && input[i] != '-' && input[i] != '*'
&& input[i] != '/' && input[i] != '^')
{
char a[] = {input[i],'/0'};
stack.push(a);
}
else
{
std::string num1, num2,temp;
if(!stack.empty())
{
num1 = stack.top();
stack.pop();
}
switch(input[i])
{
case '+':
if(!stack.empty())
{
temp = stack.top() + "+" + num1;
stack.pop();
stack.push(temp);
}
break;
case '-':
if(!stack.empty())
{
temp = stack.top() + "-" + num1;
stack.pop();
stack.push(temp);
}
break;
case '*':
if(!stack.empty())
{
temp = stack.top() + "*" + num1;
stack.pop();
stack.push(temp);
}
break;
case '/':
if(!stack.empty())
{
temp = stack.top() + "/" + num1;
stack.pop();
stack.push(temp);
}
break;
case '^':
if(!stack.empty())
{
temp = stack.top() + "^" + num1;
stack.pop();
stack.push(temp);
}
break;
default:
break;
}
}
}
if(stack.size() == 1)
{ return stack.top(); }
else
{ return "-1"; }
}
#endif
//main.cpp
#include "itopconvert.hpp"
#include "ptoiconvert.hpp"
#include <iostream>
using namespace std;
int main()
{
string input;
cin >> input;
cout << postfixToInfix(infixToPostfix(input));
return 0;
}