Infix to Postfix using Stacks w/ Professor's Algorithm - c++

Been scratching my head for hours already and I have no clue what my mistake is. I'm following my professor's derived algorithm step by step and I don't know why it isn't working properly.
Here's the derived Algorithm:
Here's the code that I tried to make:
#include <iostream>
#include "ecpe202.h"
#define Max 100
using namespace std;
int getICP(char x){
if (x == ')'){
return 0;
}
else if (x == '^'){
return 4;
}
else if (x == '*' || x == '/'){
return 2;
}
else if (x == '+' || x == '-'){
return 1;
}
else if (x == '('){
return 4;
}
}
int getISP(char x){
if (x == ')'){
return 0;
}
else if (x == '^'){
return 3;
}
else if (x == '*' || x == '/'){
return 2;
}
else if (x == '+' || x == '-'){
return 1;
}
else if (x == '('){
return 0;
}
}
bool isOperator(char ch){
if (ch == '+' || ch == '-' || ch == '*' || ch == '/' || ch == '^' || ch == '*' || ch == '(' || ch == ')'){
return (true);
}
else{
return (false);
}
}
int main(){
char infix[Max];
char ch;
int length;
myQueue que;
myStack stk;
createQ(que);
createS(stk);
cout << "Enter an infix Expression: ";
cin >> infix;
cout << endl << endl;
cout << "The postfix Expression: ";
length = strlen(infix);
for (int i = 0; i < length; i++){
addQ(que, infix[i]);
}
while (!isEmptyQ(que)){
ch = retrieveQ(que);
//start of infix to postfix algo
//1. push
if (ch == '('){
pushS(stk, ch);
}
//2. if scanned is operand
if (!isOperator(ch)){
cout << ch;
}
else{
//2.1 push if...
if (isEmptyS(stk) || getICP(ch) > getISP(topS(stk)) || topS(stk) == '('){
pushS(stk, ch);
}
//2.2. pop all operators
else{
while(!isEmptyS(stk) && getISP(topS(stk)) >= getICP(ch) || topS(stk) == '('){
cout << popS(stk);
}
}
pushS(stk, ch);
}
//3. If scanned ')'
bool loop = true;
if (ch == ')'){
do{
if (ch == '('){
loop = false;
}
else{
cout << popS(stk);
}
}while(loop == true);
}
//repeat 1-3
}
cout << endl;
}
For the ecpe202.h:
#include<dos.h>
#include<windows.h>
#define FOREVER true
#define MAXSTACK 100
#define MAXQUEUE 100
using namespace std;
struct myStack{
int tos;
char s[MAXSTACK];
};
struct myQueue{
int head, tail, q[MAXQUEUE];
};
//STACK
void createS(myStack &S){
S.tos=-1;
}
void pushS(myStack &S, char item){
S.s[++S.tos] = item;
}
char popS(myStack &S){
return(S.s[S.tos--]);
}
char topS(myStack S){
return (S.s[S.tos]);
}
bool isFullS(myStack S){
if(S.tos == MAXSTACK - 1)
return true;
return false;
}
bool isEmptyS(myStack S){
if (S.tos == -1)
return true;
return false;
}
//QUEUE
void createQ(myQueue &Q){
Q.head = 0;
Q.tail = 0;
}
void addQ(myQueue &Q, char item){
Q.q[Q.tail++] = item;
Q.tail %= MAXQUEUE;
}
char retrieveQ(myQueue &Q){
char temp;
temp = Q.q[Q.head++];
Q.head %= MAXQUEUE;
return temp;
}
bool isFullQ(myQueue Q){
if (Q.tail == MAXQUEUE)
return true;
return false;
}
bool isEmptyQ(myQueue Q){
if (Q.tail == Q.head)
return true;
return false;
}
//GOTOXY
void gotoxy(int x, int y){
COORD coord;
coord.X = x;
coord.Y = y;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
}
void clrscr(){
system("CLS");
}
The output that my code:
What seems to be wrong in my program? tried re-reading it a couple of times and I still can't fix it.

Related

g++ saying function doesn't exist even when including the proper header

So I am working on some homework for my uni and need to convert a string to a float. For whatever reason g++ is complaining that the 'stof' function doesn't exist. Although I have included the required header. Here is my code, the error is on the line that says
holder = stof(x.substr(0, end_of_num));
#include <iostream>
#include <string>
#include <list>
using namespace std;
float process_func(string x);
bool isPartOfNum(char x);
int main() {
string x;
while (true) {
cout << "input a string" << endl;
getline(cin, x);
cout << process_func(x);
}
return 0;
}
float process_func(string x) {
int end_of_num =0;// used to find last index from num
int negMult = 1; //used to multiply value at end if there was a negative
bool onNum = false; //used to
list <float> numList;
list <char> operList;
if ((x.at(0) < 48 || x.at(0) > 57) && x.at(0) != '-') //check if start of string doesnt have a number or negative symbol
return -1;
if (x.at(0) != '-')
negMult = -1;
float holder;// temp holder for floats
int i = 0;
while (i<x.length()) {
if (isPartOfNum(x.at(i))) {
end_of_num++;
onNum = true;
}
else if (onNum) {
holder = stof(x.substr(0, end_of_num));
numList.push_back(holder); //adds num as float to list
x.erase(0, end_of_num + 1); //+1 removes the space after the number before the operator
end_of_num = 0;
onNum = false;
}
if (x.at(i) == '+' || x.at(i) == '-' || x.at(i) == '*' || x.at(i) == '/') {
operList.push_back(x.at(i));
}
} //at this point both lists should be full of all needed pieces of info
int answer = 0;
int temp;
bool firstOper=true; // used to hold first operation
while (numList.size() >=2) { //requires at least 2 entries for last operation
while (!operList.empty()) {
temp = numList.front();
numList.pop_front();
if (operList.front() == '+') {
if (firstOper) {
answer = temp + numList.front();
numList.pop_front();
firstOper = false;
}
else {
answer += temp;
}
}
else if (operList.front() == '-') {
if (firstOper) {
answer = temp - numList.front();
numList.pop_front();
firstOper = false;
}
else {
answer -= temp;
}
}
else if (operList.front() == '*') {
if (firstOper) {
answer = temp * numList.front();
numList.pop_front();
firstOper = false;
}
else {
answer *= temp;
}
}
else if (operList.front() == '/') {
if (firstOper) {
answer = temp / numList.front();
numList.pop_front();
firstOper = false;
}
else {
answer /= temp;
}
}
operList.pop_front();
}
}
return answer;
}
bool isPartOfNum(char x) {
if ((x >= 48 && x <= 57) || (x == '-' || x == '.'))
return true;
return false;
}
Solved by compiling using c++ 11

Conversion of infix to postfix: stack is not recognized error

I am a beginner using the stack so I been trying to do different exercises on it. I'm trying to convert infix->postfix. The xcode debugger says "Use of class template 'stack'requires template arguments'. Here is my code.
#include<iostream>
#include<stack>
#include<string>
using namespace std;
bool IsOperand(char ch)
{
if ((ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z')) {
return true;
}
return false;
}
bool IsOperator(char C)
{
if (C == '+' || C == '-' || C == '*' || C == '/' || C == '^') {
return true;
}
return false;
}
bool IsLeftParenthesis(char ch)
{
if (ch == '(') {
return true;
}
return false;
}
bool IsRightParenthesis(char ch)
{
if (ch == ')') {
return true;
}
return false;
}
bool Flag(char ch)
{
if (!IsOperand(ch) || !IsOperator(ch) || !IsLeftParenthesis(ch) || !IsRightParenthesis(ch)) {
return false;
}
return true;
}
int IsRightAssociative(char op)
{
if (op == '^') {
return true;
}
return false;
}
int GetOperatorWeight(char op)
{
int weight = -1;
switch (op) {
case '+':
case '-':
weight = 1;
break;
case '*':
case '/':
weight = 2;
break;
case '^':
weight = 3;
break;
}
return weight;
}
bool HasHigherPrecedence(char op1, char op2)
{
int op1Weight = GetOperatorWeight(op1);
int op2Weight = GetOperatorWeight(op2);
// If operators have equal precedence, return true if they are left associative.
// BUT REMEMBER...return false, if right associative.
// if operator is left-associative, left one should be given priority.
if (op1Weight == op2Weight) {
if (IsRightAssociative(op1)) {
return false;
}
else {
return true;
}
}
return op1Weight > op2Weight ? true : false;
}
string InfixToPostfix(string expression)
{
stack S;
string postfix = "";
for (auto& elem : expression) {
if (Flag(elem)) {
continue;
}
// If character is operator, pop two elements from stack, perform operation and push the result back.
else if (IsOperator(elem)) {
while (!S.empty() && S.top() != '(' && HasHigherPrecedence(S.top(), elem)) {
postfix += S.top();
S.pop();
}
S.push(elem);
}
else if (IsOperand(elem)) {
postfix += elem;
}
else if (elem == '(') {
S.push(elem);
}
else if (elem == ')') {
while (!S.empty() && S.top() != '(') {
postfix += S.top();
S.pop();
}
S.pop();
}
}
while (!S.empty()) {
postfix += S.top();
S.pop();
}
return postfix;
}
int main()
{
// std::string expression = "54/(5^2)+(6^2^3)";
std::string expression = "A+(BC-(D/E^F)G)H";
std::string postfix = InfixToPostfix(expression);
std::cout << "Output = " << postfix << "\n";
}
Here specificially where the error is happening.
string InfixToPostfix(string expression)
{
stack S;
It says
Stack S -> Use of class template 'stack'requires template arguments'
Stack is a container, you need to specify the type of the container like:
stack <int> S;
or in you case it is stack of char:
stack <char> S;

C++ Infix to Postfix program, Stack is continuously empty?

I'm working on a program for a computer science class. I have everything completed and separated into the interface/implementation and for some reason, the program loops infinitely and says "Stack is empty!" after the peek() function is called.
I've tried inserting cout << statements to see if I can pinpoint the issue, however, no luck. I would appreciate it if someone else could take a look at it.
Thank You
Header
#ifndef STACK_H
#define STACK_H
/////////////////////////////////////////////////////
////Includes/////////////////////////////////////////
/////////////////////////////////////////////////////
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <stdlib.h>
#include <iomanip>
#include <sstream>
#include <stdio.h>
/////////////////////////////////////////////////////
using namespace std;
/*-------------------------------------------------------------------------------------------------------------*/
template <typename Object>
class Stack
{
private:
class stackListNode
{
public:
Object data;
stackListNode *next;
private:
//Nothing to declare-->placeholder since class
//sets data members to private initially
};
stackListNode *top;
public:
/////////////////////////////////////////////////
//Constructor Function//////////////////////////
Stack() {top = NULL;}
/////////////////////////////////////////////////
//Rest of functions defined inline for simplicity
void push(char token) // Push token onto the stack and create new node for top of stack
{
stackListNode *newNode = new stackListNode;
newNode->data = token;
newNode->next = top;
top = newNode;
}
int pop()
{
if(empty())
{
cout << "Stack is empty!\n" << endl;
return NULL;
}
stackListNode *temp = top;
top = temp->next;
}
char peek()
{
if(empty())
{
cout << "Stack is empty!\n" << endl;
return NULL;
}
return top->data;
}
int empty()
{
return top == NULL;
}
};
#endif
Main File:
/////////////////////////////////////////////////////
////Includes/////////////////////////////////////////
/////////////////////////////////////////////////////
#include <iostream>
#include <fstream>
#include <string>
#include "Stack.h"
/////////////////////////////////////////////////////
using namespace std;
int precendence(char stack_beginning); //ensures order of operations.
int precendence(char*myArray);
void InFixToPostfix(ifstream& in_file);
double EvaluatePostfix(double first_operand, double second_operand, char*myArray);
int main()
{
////VARS/////////////////////////////////////////////
string absolutePath;
cout << endl;
cout << "Please type in the name of the file you would to open \n";
cin >> absolutePath;
ifstream in_file;
in_file.open(absolutePath.c_str());
if(!in_file)
{
cout << "failed to open input file\n" ;
return 1 ;
}
else
{
InFixToPostfix(in_file); //kicks off program
}
}
void InFixToPostfix(ifstream& in_file)
{
string infix;
int right_parentheses =0;
int left_parentheses =0;
while(getline(in_file, infix))
{
char myArray[infix.size()];
strcpy(myArray, infix.c_str());
for(int i = 0; i < sizeof(myArray); i++)
{
if(myArray[i] == '(')
{
right_parentheses++;
}
if(myArray[i] == ')')
{
left_parentheses++;
}
}
if(right_parentheses!=left_parentheses)
{
cout << endl;
cout << "There is a typo in one of the expressions in your file \n";
cout << "Please fix it and rerun the program \n";
exit(1);
}
for(int i = 0; i < sizeof(myArray); i++)
{
//int number = int(myArray[i]);
//deferences the pointer and reads each char in the array
//as an int rather than a character.
//int number = myArray[i];
if(isxdigit(myArray[i]) > 0) //function used to check for hexidecimal values (i.e. int's)
{
goto exit_out;
}
else if(myArray[i] == '(' || myArray[i] == ')' || myArray[i] == '+' || myArray[i] == '-' || myArray[i] == '*' || myArray[i] == '/' || myArray[i] == '\\' || myArray[i] == '\n')
{
goto exit_out;
}
else if(myArray[i] == char(32)) //checks to see if there is a space
{
goto exit_out;
}
else
{
cout << endl;
cout << "There is an invalid character in the file\n";
exit(1);
}
exit_out:;
}
////////Declares a STRING Stack////////////////////////////////
Stack<char> stack_string;
////////Declares an Int Stack/////////////////////////////////
Stack<int> stack_int;
//////////////////////////////////////////////////////////////
for(int i = 0; i < sizeof(myArray); i++)
{
int number = isxdigit(myArray[i]);
if(number > 0)
{
cout << number;
//outputs the number b/c it is an operand
}
if(myArray[i] == '(')
{
stack_string.push(myArray[i]);
}
if(myArray[i] == ')')
{
//cout << "test";
while(stack_string.peek() != '(')
{
cout << stack_string.peek();
stack_string.pop(); //pops to the peek
}
stack_string.pop(); // if there is a ), pops to the peek
}
if(myArray[i] == '+' || myArray[i] == '-' || myArray[i] == '/' || myArray[i] == '*')
{
if(stack_string.empty())
{
stack_string.push(myArray[i]); //if there's nothing on the stack, pushes the current character
//goto done;
break; //breaks out of the statement
}
char stack_beginning = stack_string.peek();
int stack_top = precendence(stack_beginning);
//int stack_top = precendence(stack_string.peek());
int operatorHierarchy = precendence(myArray);
//must be declared here because i will have been interated through array
if(operatorHierarchy > stack_top)
{
stack_string.push(myArray[i]);
}
else if(operatorHierarchy <= stack_top) //could also be an if
{
dump_out:;
cout << stack_string.peek();
stack_string.pop();
int rerunThroughStack =0;
char new_stack_beginning = stack_string.peek();
rerunThroughStack = precendence(new_stack_beginning);
if(operatorHierarchy < stack_top)
{
stack_string.push(myArray[i]);
goto done; //could break
}
if(stack_string.peek() == '(')
{
stack_string.push(myArray[i]);
goto done;
}
if(stack_string.empty())
{
stack_string.push(myArray[i]);
goto done;
}
goto dump_out;
}
}
done:;
}
cout << stack_string.peek() << endl;
//////////Evaluate Section/////////////////////////////
for(int i = 0; i < sizeof(myArray); i++)
{
if(isxdigit(myArray[i]) > 0) //this is a number
{
stack_int.push(isxdigit(myArray[i]));
goto end;
}
else if(myArray[i] == '*' || myArray[i] == '+' || myArray[i] == '-' || myArray[i] == '/')
{
double first_operand;
first_operand = stack_int.peek(); //fetches first operand on the stack_int
stack_int.pop();
//////////////////
double second_operand;
second_operand = stack_int.peek();
stack_int.pop();
//////////////////
double answer;
answer = EvaluatePostfix(first_operand, second_operand, myArray); //THIS PROBABLY IS NOT RIGHT
stack_int.push(answer);
}
end:;
}
/*
int size_of_stack;
size_of_stack = stack_int.size();
if(size_of_stack == 1)
{
cout << stack_int.peek();
}
*/
}
}
double EvaluatePostfix(double first_operand, double second_operand, char* myArray) //might have to pass array as reference
{
/*
Cycle through the characters passed in through myArray[i];
*/
for(int i = 0; i < sizeof(myArray); i++)
{
if(myArray[i] == '*')
{
double first_answer;
first_answer = (second_operand * first_operand);
return first_answer;
}
else if(myArray[i] == '/')
{
double second_answer;
second_answer = (second_operand / first_operand);
return second_answer;
}
else if(myArray[i] == '+')
{
double third_answer;
third_answer = (second_operand + first_operand);
return third_answer;
}
else if(myArray[i] == '-')
{
double fourth_answer;
fourth_answer = (second_operand - first_operand);
return fourth_answer;
}
/*
else
{
cout << "There must be an error in your file" <<endl;
break;
exit(1);
}
*/
}
}
int precendence(char stack_beginning)
{
int precendence;
if(stack_beginning == '*' || stack_beginning == '/')
{
precendence = 2;
return precendence;
}
//by making it 2, the precendence is dubbed less than +/-
if(stack_beginning == '+' || stack_beginning == '-')
{
precendence = 1;
return precendence;
}
} //by making it 1, the precendence is dubbed greater than */"/"
int precendence(char*myArray)
{
int precendence;
for(int i = 0; i < sizeof(myArray); i++)
{
if(myArray[i] == '*' || myArray[i] == '/')
{
precendence = 2;
return precendence;
}
//by making it 2, the precendence is dubbed less than +/-
if(myArray[i] == '+' || myArray[i] == '-')
{
precendence = 1;
return precendence;
}
} //by making it 1, the precendence is dubbed greater than */"/"
}

Infix to Postfix calculator, implement sin cos and X&Y variables?

I'm pretty green at C++, and I have to make an infix to postfix calculator that supports sin() and cos(), and it has to be a 2 variable function, something like z=3x*sin(3+4y), I already got the parser from infix to postfix, but I don't know how to implement sin and cos, I've been told that I could set them as operator, like +, -, /, etc. and to set a specific token for them, like "s" for sin() and "c" for cos() but I don't exactly know how, and I don't know either how to implement the variables x & y, I know that this is not something I should be asking, but I'm just tired and desperate.
Here's the code I have. I'm using Ubuntu 11:
#include <iostream>
#include <cmath>
#include <cstdlib>
#include <string>
#define MAX_SIZE 20
using namespace std;
template<class T> class Stack
{
private:
T item[MAX_SIZE];
int top;
public:
Stack()
{
top = -1;
}
void push(T data)
{
if(!this->is_full())
item[++top] = data;
else
{
cout << "Stack Error" << endl;
exit(10);
}
}
T pop()
{
if(!this->is_empty())
{
return item[top--];
}
else
{
cout << "Stack is Empty" << endl;
exit(11);
}
}
int size()
{
return top + 1;
}
bool is_empty()
{
if(top == -1)
return true;
else
return false;
}
bool is_full()
{
if(top == MAX_SIZE - 1)
return true;
else
return false;
}
void display()
{
for(int i = 0; i < this->size(); i++)
{
cout << item[i] << " ";
}
cout << endl;
}
T return_top()
{
return item[top];
}
};
class Convert
{
private:
bool num_flag;
bool two_digit_flag;
public:
Convert();
string return_with_bracket(string infix);
void to_Postfix(string infix,char postfix[]);
bool prcd(char op1, char op2);
int isOperand(char op);
int isOperator(char op);
bool return_flag()
{
return num_flag;
}
};
Convert::Convert()
{
this->num_flag = false;
this->two_digit_flag = false;
}
string Convert::return_with_bracket(string infix)
{
return("(" + infix + ")");
}
bool Convert::prcd(char op1, char op2)
{
if((op1 == '+' || op1 == '-' || op1 == '*' || op1 == '/') && op2 == '(')
return true;
if(op1=='+' && op2=='+')
return true;
if(op1=='-' && op2=='-')
return false;
if(op1=='-' && op2=='+')
return false;
if(op1=='+' && op2=='-')
return false;
if(op1=='/' && op2=='/')
return false;
if(op1=='/' && (op2=='-' || op2=='+'))
return true;
if(op1=='*' && (op2=='+' || op2=='-'))
return true;
if((op1 == '-' || op1 == '+') && (op2 =='*' || op2 == '/'))
return false;
if((op1 == '$' || op1 == '+') && (op2 =='*' || op2 == '/' || op2=='-'))
return true;
if((op1 == '-' || op1 == '+' || op1 =='*' || op1 == '/')&& op2=='^')
return false;
if(op1 == '^' && ( op2 == '+' || op2 =='*' || op2 == '/' || op2=='-'))
return false;
}
int Convert::isOperand(char op)
{
return(op >= '0' && op <= '9');
}
int Convert::isOperator(char op)
{
return(op =='+' || op =='-' || op == '/' || op =='*' || op =='^');
}
void Convert::to_Postfix(string infix, char postfix[])
{
int position, outpos=0;
char c;
int count = 0;
char temp;
char stacktop;
Stack<char> stack;
for(position = 0; (c = infix[position]) != '\0'; position++)
{
if(this->isOperand(c))
{
postfix[outpos++] = c;
this->num_flag = true;
count++;
if(count >= 2)
{
this->two_digit_flag = true;
}
}
else if(this->isOperator(c))
{
count = 0;
if(isOperator(infix[position]) && isOperator(infix[position + 1]))
{
cout << " '\' aMissing argument in between " << infix[position] << " and " << infix[position + 1] << " in column " << position + 1 << endl;
exit(9);
}
if(this->prcd(c, stacktop))
{
stacktop = stack.return_top();
stack.push(c);
stacktop = c;
}
else
{
while(true)
{
temp = stack.pop();
postfix[outpos++] = temp;
stacktop = stack.return_top();
if(prcd(c, stacktop) || stacktop == '(')
break;
}
stack.push(c);
stacktop = stack.return_top();
}
}
else if(c == '(')
{
count = 0;
stack.push(c);
stacktop = stack.return_top();
}
else if(c == ')')
{
count = 0;
while(1)
{
if(stack.size() == 0)
{
cout << "Warning!! Number of ')' is greater than '('" << endl;
exit(2);
}
temp = stack.pop();
if(temp != '(')
{
postfix[outpos++] = temp;
}
else
{
break;
}
}
stacktop = stack.return_top();
}
else
{
cout << "Invalid input";
exit(3);
}
if(infix[position] == ')' && infix[position + 1] == '(')
{
stack.push('*');
stacktop = stack.return_top();
}
}
if(stack.size() != 0)
{
cout << "Warning!!Number of '(' is greater than ')'" << endl;
// exit(6);
}
if(!this->return_flag())
{
cout << "You must Enter Numeric value for calculation" << endl;
cout << "This program cannot perform operations on variables";
exit(5);
}
if(this->two_digit_flag)
{
cout << "Sory! Althoug u may have entered right string" << endl;
cout << "this program is only for single digit operation" << endl;
exit(8);
}
postfix[outpos] = '\0';
}
class Evaluate
{
public:
double eval(char expr[], Convert &);
double oper(int symb, double op1, double op2);
};
double Evaluate::oper(int symb, double op1, double op2)
{
switch(symb)
{
case '+': return (op1 + op2);
case '-': return (op1 - op2);
case '*': return (op1 * op2);
case '/': return (op1 / op2);
case '^': return (pow(op1, op2));
}
}
double Evaluate::eval(char expr[], Convert &convert)
{
int c, position;
char temp1;
int count = 0;
double opnd1, opnd2, value;
Stack<double> stack;
for(position = 0; (c = expr[position]) != '\0'; position++)
{
if(convert.isOperand(c))
{
temp1 = double(c - '0');
stack.push(temp1);
}
else
{
opnd2 = stack.pop();
if(stack.size() == 0)
{
cout << "This program cannot process unary operation";
exit(1);
}
opnd1 = stack.pop();
value = oper(c, opnd1, opnd2);
stack.push(value);
}
}
if(stack.size() >= 2)
{
cout << "Sory! this program cannot calculate this" << endl;
cout << "Enter +, *, /, - or ^ between bracket" << endl;
exit(4);
}
return (stack.pop());
}
int main()
{
Convert convert;
Evaluate evaluate;
string bracketted_infix;
char infix[50], postfix[50];
char choice;
while(1)
{
cout << "Enter string: ";
cin >> infix;
cout << endl;
cout << "Entered String: " << infix << endl;
bracketted_infix = convert.return_with_bracket(infix);
convert.to_Postfix(bracketted_infix, postfix);
cout << "Equivalent Postfix string: " << postfix << endl;
cout << "RESULT: ";
cout << evaluate.eval(postfix, convert);
cout << "\nCalculate another string?(y/n) ";
cin >> choice;
cout << endl;
if(choice == 'n')
break;
}
return 0;
}

Binary Operads sample program

Problem Statement :
Write a C++ program to evaluate postfix expressions. Your program should take postfix expression as an input, process it with the help of stack and display the result after performing required calculations.
Only following Binary operators are allowed for this program:
+, -, *, /, ^ [addition, subtraction, multiplication, division, exponentiation]
If some error occurs while processing postfix expression, your program should display a meaningful message, like:
Error: Division by zero not allowed
Error: Two operands required for __ operator
Error: Invalid postfix expression
Help me with it, My program is generating errors This is my try:
#include<iostream>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<string>
#define MAX_SIZE 20
using namespace std;
template<class T>
class Stack
{
private:
T item[MAX_SIZE];
int top;
public:
Stack()
{
top = -1;
}
void push(T data)
{
if(!this->is_full())
item[++top] = data;
else
{
cout<<"Stack Error"<<endl;
exit(10);
}
}
T pop()
{
if(!this->is_empty())
return item[top--];
else
{
cout<<"Stack is Empty"<<endl;
exit(11);
}
}
int size()
{
return top+1;
}
bool is_empty()
{
if(top==-1)
return true;
else
return false;
}
bool is_full()
{
if(top==MAX_SIZE-1)
return true;
else
return false;
}
void display()
{
for(int i=0; i<this->size(); i++)
{
cout<<item[i]<<" ";
}
cout<<endl;
}
T return_top()
{
return item[top];
}
};
class Convert
{
private:
bool num_flag;
bool tow_digit_flag;
public:
Convert();
string return_with_bracket(string infix);
void to_Postfix(string infix,char postfix[]);
bool prcd(char op1, char op2);
int isOperand(char op);
int isOperator(char op);
bool return_flag()
{
return num_flag;
}
};
Convert::Convert()
{
this->num_flag = false;
this->tow_digit_flag = false;
}
string Convert::return_with_bracket(string infix)
{
return("(" + infix + ")");
}
bool Convert::prcd(char op1, char op2)
{
if((op1=='+' || op1=='-' || op1=='*' || op1=='/') && op2=='(' )
return true;
if(op1=='+' && op2=='+')
return true;
if(op1=='-' && op2=='-')
return false;
if(op1=='-' && op2=='+')
return false;
if(op1=='+' && op2=='-')
return false;
if(op1=='/' && op2=='/')
return false;
if(op1=='/' && (op2=='-' || op2=='+'))
return true;
if(op1=='*' && (op2=='+' || op2=='-'))
return true;
if((op1 == '-' || op1 == '+') && (op2 =='*' || op2 == '/'))
return false;
if((op1=='$' || op1 == '+') && (op2 =='*' || op2 == '/' || op2=='-'))
return true;
if((op1 == '-' || op1 == '+' || op1 =='*' || op1 == '/')&& op2=='^')
return false;
if(op1 == '^' && ( op2 == '+' || op2 =='*' || op2 == '/' || op2=='-'))
return false;
}
int Convert::isOperand(char op)
{
return(op>= '0' && op <= '9');
}
int Convert::isOperator(char op)
{
return(op=='+' || op=='-' || op == '/' || op=='*' || op=='^');
}
void Convert::to_Postfix(string infix, char postfix[])
{
int position, outpos=0;
char c;
int count = 0;
char temp;
char stacktop ;
Stack<char> stack;
for(position = 0; (c = infix[position])!='\0'; position++)
{
if(this->isOperand)
{
postfix[outpos++] = c;
this->num_flag = true;
count++;
if(count>=2)
{
this->tow_digit_flag = true;
}
}
else if(this->isOperator©)
{
count = 0;
if(isOperator(infix[position]) && isOperator(infix[position+1]))
{
cout<<"\aMissing argument in between "<<infix[position]<<" and "<<infix[position+1]
<<" in column "<< position+1<<endl;
exit(9);
}
if(this->prcd(c, stacktop))
{
stacktop=stack.return_top();
stack.push©;
stacktop = c;
}
else
{
while(true)
{
temp = stack.pop();
postfix[outpos++] =temp;
stacktop = stack.return_top();
if(prcd(c, stacktop) || stacktop=='(')
break;
}
stack.push©;
stacktop = stack.return_top();
}
}
else if(c=='(')
{
count = 0;
stack.push©;
stacktop = stack.return_top();
}
else if(c==')')
{
count = 0;
while(1)
{
if(stack.size()==0)
{
cout<<"Warning!! Number of ')' is greater than '('" <<endl;
exit(2);
}
temp = stack.pop();
if(temp!='(')
{
postfix[outpos++] = temp;
}
else
{
break;
}
}
stacktop =stack.return_top();
}
else
{
cout<<"Invalid input";
exit(3);
}
if(infix[position]==')' && infix[position+1]=='(')
{
stack.push('*');
stacktop = stack.return_top();
}
}
if(stack.size()!=0)
{
cout<<"Warning!!Number of '(' is greater than ')'"<<endl;
// exit(6);
}
if(!this->return_flag())
{
cout<<"You must Enter Numeric value for calculation"<<endl;
cout<<"This program cannot perform operations on variables";
exit(5);
}
if(this->tow_digit_flag)
{
cout<<"Sory! Althoug u may have entered right string"<<endl;
cout<<"this program is only for single digit operation"<<endl;
exit(8);
}
postfix[outpos] = '\0';
}
class Evaluate
{
public:
double eval(char expr[], Convert &Wink;
double oper(int symb, double op1, double op2);
};
double Evaluate::oper(int symb, double op1, double op2)
{
switch(symb)
{
case '+':
return (op1 + op2);
case '-':
return (op1 - op2);
case '*':
return (op1 * op2);
case '/':
return (op1 / op2);
case '^':
return (pow(op1, op2));
}
}
double Evaluate::eval(char expr[],Convert &convert)
{
int c, position;
char temp1;
int count = 0;
double opnd1, opnd2, value;
Stack<double> stack;
for(position = 0; (c = expr[position])!='\0'; position++)
{
if(convert.isOperand©)
{
temp1 = double(c-'0');
stack.push(temp1);
}
else
{
opnd2 = stack.pop();
if(stack.size()==0)
{
cout<<"This program cannot process unary operation";
exit(1);
}
opnd1 = stack.pop();
value = oper(c, opnd1, opnd2);
stack.push(value);
}
}
if(stack.size()>=2)
{
cout<<"Sory! this program cannot calculate this"<<endl;
cout<<"Enter +, *, /, - or ^ between bracket"<<endl;
exit(4);
}
return (stack.pop());
}
int main()
{
Convert convert;
Evaluate evaluate;
string bracketted_infix;
char infix[50], postfix[50];
char choice;
while(1)
{
cout<<"Enter operation: ";
cin>>infix;
cout<<endl;
cout<<"Entered operation: "<<infix<<endl;
bracketted_infix = convert.return_with_bracket(infix);
convert.to_Postfix(bracketted_infix, postfix);
cout<<"Equivalent Postfix operation: "<<postfix<<endl;
cout<<"RESULT: ";
cout<<evaluate.eval(postfix, convert);
cout<<"\nCalculate another operation?(y/n) ";
cin>>choice;
cout<<endl;
if(choice=='n')
break;
}
return 0;
}
To get it actually compiling you need to fix two syntax errors;
On line 154 you are calling a method with no parameter,
but the only declaration of this method takes 1 parameter.
if (this->isOperand) {
I believe you may have meant:
if (this->isOperand(c)) {
Also on line 255 you have a missing bracket before the semicolon:
double eval(char expr[], Convert &Wink;
When I actually ran your code it failed at runtime, with VS2010 giving an error "string subscript out of range".
If you're not already, I would recommend using a good IDE (such as Visual C++) when developing; the syntax colouring and support for dynamic debugging (i.e. breakpoints and watches) would be very helpful to debug a program like this.
Here is the final solution
#include<iostream>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<string>
#define MAX_SIZE 20
using namespace std;
template<class T>
class Stack
{
private:
T item[MAX_SIZE];
int top;
public:
Stack()
{
top = -1;
}
void push(T data)
{
if(!this->is_full())
item[++top] = data;
else
{
cout<<"Stack Error"<<endl;
exit(10);
}
}
T pop()
{
if(!this->is_empty())
return item[top--];
else
{
cout<<"Stack is Empty"<<endl;
exit(11);
}
}
int size()
{
return top+1;
}
bool is_empty()
{
if(top==-1)
return true;
else
return false;
}
bool is_full()
{
if(top==MAX_SIZE-1)
return true;
else
return false;
}
void display()
{
for(int i=0; i<this->size(); i++)
{
cout<<item[i]<<" ";
}
cout<<endl;
}
T return_top()
{
return item[top];
}
};
class Convert
{
private:
bool num_flag;
bool tow_digit_flag;
public:
Convert();
string return_with_bracket(string infix);
void to_Postfix(string infix,char postfix[]);
bool prcd(char op1, char op2);
int isOperand(char op);
int isOperator(char op);
bool return_flag()
{
return num_flag;
}
};
Convert::Convert()
{
this->num_flag = false;
this->tow_digit_flag = false;
}
string Convert::return_with_bracket(string infix)
{
return("(" + infix + ")");
}
bool Convert::prcd(char op1, char op2)
{
if((op1=='+' || op1=='-' || op1=='*' || op1=='/') && op2=='(' )
return true;
if(op1=='+' && op2=='+')
return true;
if(op1=='-' && op2=='-')
return false;
if(op1=='-' && op2=='+')
return false;
if(op1=='+' && op2=='-')
return false;
if(op1=='/' && op2=='/')
return false;
if(op1=='/' && (op2=='-' || op2=='+'))
return true;
if(op1=='*' && (op2=='+' || op2=='-'))
return true;
if((op1 == '-' || op1 == '+') && (op2 =='*' || op2 == '/'))
return false;
if((op1=='$' || op1 == '+') && (op2 =='*' || op2 == '/' || op2=='-'))
return true;
if((op1 == '-' || op1 == '+' || op1 =='*' || op1 == '/')&& op2=='^')
return false;
if(op1 == '^' && ( op2 == '+' || op2 =='*' || op2 == '/' || op2=='-'))
return false;
}
int Convert::isOperand(char op)
{
return(op>= '0' && op <= '9');
}
int Convert::isOperator(char op)
{
return(op=='+' || op=='-' || op == '/' || op=='*' || op=='^');
}
void Convert::to_Postfix(string infix, char postfix[])
{
int position, outpos=0;
char c;
int count = 0;
char temp;
char stacktop ;
Stack<char> stack;
for(position = 0; (c = infix[position])!='\0'; position++)
{
if (this->isOperand(c))
{
postfix[outpos++] = c;
this->num_flag = true;
count++;
if(count>=2)
{
this->tow_digit_flag = true;
}
}
else if(this->isOperator(c))
{
count = 0;
if(isOperator(infix[position]) && isOperator(infix[position+1]))
{
cout<<"\aMissing argument in between "<<infix[position]<<" and "<<infix[position+1]
<<" in column "<< position+1<<endl;
exit(9);
}
if(this->prcd(c, stacktop))
{
stacktop=stack.return_top();
stack.push(c);
stacktop = c;
}
else
{
while(true)
{
temp = stack.pop();
postfix[outpos++] =temp;
stacktop = stack.return_top();
if(prcd(c, stacktop) || stacktop=='(')
break;
}
stack.push(c);
stacktop = stack.return_top();
}
}
else if(c=='(')
{
count = 0;
stack.push(c);
stacktop = stack.return_top();
}
else if(c==')')
{
count = 0;
while(1)
{
if(stack.size()==0)
{
cout<<"Warning!! Number of ')' is greater than '('" <<endl;
exit(2);
}
temp = stack.pop();
if(temp!='(')
{
postfix[outpos++] = temp;
}
else
{
break;
}
}
stacktop =stack.return_top();
}
else
{
cout<<"Invalid input";
exit(3);
}
if(infix[position]==')' && infix[position+1]=='(')
{
stack.push('*');
stacktop = stack.return_top();
}
}
if(stack.size()!=0)
{
cout<<"Warning!!Number of '(' is greater than ')'"<<endl;
// exit(6);
}
if(!this->return_flag())
{
cout<<"You must Enter Numeric value for calculation"<<endl;
cout<<"This program cannot perform operations on variables";
exit(5);
}
if(this->tow_digit_flag)
{
cout<<"Sory! Althoug u may have entered right string"<<endl;
cout<<"this program is only for single digit operation"<<endl;
exit(8);
}
postfix[outpos] = '\0';
}
class Evaluate
{
public:
double eval(char expr[], Convert &Wink);
double oper(int symb, double op1, double op2);
};
double Evaluate::oper(int symb, double op1, double op2)
{
switch(symb)
{
case '+':
return (op1 + op2);
case '-':
return (op1 - op2);
case '*':
return (op1 * op2);
case '/':
return (op1 / op2);
case '^':
return (pow(op1, op2));
}
}
double Evaluate::eval(char expr[],Convert &convert)
{
int c, position;
char temp1;
int count = 0;
double opnd1, opnd2, value;
Stack<double> stack;
for(position = 0; (c = expr[position])!='\0'; position++)
{
if(convert.isOperand(c))
{
temp1 = char(c-'0');
stack.push(temp1);
}
else
{
opnd2 = stack.pop();
if(stack.size()==0)
{
cout<<"This program cannot process unary operation";
exit(1);
}
opnd1 = stack.pop();
value = oper(c, opnd1, opnd2);
stack.push(value);
}
}
if(stack.size()>=2)
{
cout<<"Sory! this program cannot calculate this"<<endl;
cout<<"Enter +, *, /, - or ^ between bracket"<<endl;
exit(4);
}
return (stack.pop());
}
int main()
{
Convert convert;
Evaluate evaluate;
string bracketted_infix;
char infix[50], postfix[50];
char choice;
while(1)
{
cout<<"Enter operation: ";
cin>>infix;
cout<<endl;
cout<<"Entered operation: "<<infix<<endl;
bracketted_infix = convert.return_with_bracket(infix);
convert.to_Postfix(bracketted_infix, postfix);
cout<<"Equivalent Postfix operation: "<<postfix<<endl;
cout<<"RESULT: ";
cout<<evaluate.eval(postfix, convert);
cout<<"\nCalculate another operation?(y/n) ";
cin>>choice;
cout<<endl;
if(choice=='n')
break;
}
return 0;
}