Calculator program for postfix-expressions - c++

The program should read a postfix expression consisting of numbers and operators and compute the result. I try using string but I keep getting a result that is way off. Can you please tell me what I'm doing wrong?
#include <iostream>
#include "StackADT.h"
#include <stack>
using namespace std;
#include <string>;
bool isOperator(string);
int calculate (int, char, int);
void display (int, string, int, int);
int main(){
string expr;
int operand2 = 0;
int operand1 = 0;
string thisOperator;
int value;
int result;
cout << "Evaluates a postfix expression(to Quit)." << endl;
cin >> expr;
//while(expr != "-1")
{
//getline( cin, expr,'\n' );
int exprSize = expr.size();
const int siz = 10;
char expr2[siz];
for (int i = 0; i < expr.length; i++)
{
expr2[i] = expr[i];
}
Stack<int> stack;
int index = 0;
while (index < exprSize){
if (!isOperator(expr[index]) )
{
stack.pushStack(expr[index]);
}
else
{
stack.popStack (operand2);
stack.popStack (operand1);
thisOperator = expr[index];
value = calculate (operand1, thisOperator[index], operand2);
stack.pushStack(value);
}
index++;
}
result = stack.popStack (operand1);
display(operand1, thisOperator, operand2, result );
// cout << "Evaluates a postfix expression(to Quit)." << endl;
// cin >> expr;
}
system("pause");
return 0;
}
void display (int op1, string operat, int op2, int result){
cout << op1 << operat << op2 << " = " << result;
}
bool isOperator(char token )
{
if(token == '-' || token == '+' || token == '*' || token == '/')
return true;
else
return false;
}
int calculate (int op1, char operat, int op2){
switch (operat)
{
case '/': return op1 / op2;
break;
case '+': return op1 + op2;
break;
case '*': return op1 * op2;
break;
case '-': return op1 - op2;
break;
default: cout << "Cant / by zero" << endl;
break;
}
}
I'm working off this; exprSize = length of string
createStack (stack)
index = 0
loop (index < exprSize)
if (expr[index] is operand)
pushStack (stack, expr[index])
else // expr[index] is an operator
popStack (stack, operand2)
popStack (stack, operand1)
operator = expr[index]
value = calculate (operand1, operator, operand2)
pushStack (stack, value)
end if
index = index + 1
end loop
popStack (stack, result)
return (result)

Related

Issue in reverse polish notation task in C++

The program analyzes the entered expression, converts it into reverse Polish notation and calculates the result.My program works correctly with expressions without brackets, but if I use an expression with brackets, I get an error: "Op" was nullptr. I have no idea why as my Stack "Op" must be initialized.(I marked where the error occurs in the code).
My code:
#include <iostream>
#include <string>
#include <iomanip>
struct Stack {
char info;
Stack* next;
} *begin;
int Prior(char);
Stack* InStack(Stack*, char);
Stack* OutStack(Stack*, char&);
double Result(char*);
double mas[201];
Stack* InStack(Stack* p, char in) {
Stack* t = new Stack;
t->info = in;
t->next = p;
return t;
}
Stack* OutStack(Stack* p, char& in) {
Stack* t = p;
in = p->info;
p = p->next;
delete t;
return p;
}
int Prior(char a) {
switch (a) {
case '^': return 4;
case '*': case '/': return 3;
case '-': case '+': return 2;
case '(': return 1;
}
return 0;
}
double Result(char* str) {
int i;
char ss, ss1, ss2, ssR = 'z' + 1;
double op1, op2, res = 0, mas[200];
std::cout << "Input data:" << std::endl;
for (i = 0; str[i] != '\0'; ++i)
{
ss = str[i];
if (ss >= 'a' && ss <= 'z')
{
std::cout << ss << " = ";
std::cin >> mas[int(ss)];
}
}
for (i = 0; str[i] != '\0'; ++i)
{
ss = str[i];
if (!(ss == '+' || ss == '-' || ss == '*' || ss == '/'))
{
begin = InStack(begin, ss);
}
else
{
begin = OutStack(begin, ss2);
begin = OutStack(begin, ss1);
op2 = mas[int(ss2)];
op1 = mas[int(ss1)];
switch (ss)
{
case'+':res = op1 + op2; break;
case'-':res = op1 - op2; break;
case'*':res = op1 * op2; break;
case'/':res = op1 / op2; break;
}
mas[int(ssR)] = res;
begin = InStack(begin, ssR);
ssR++;
}
}
return res;
}
int main()
{
Stack* t, * Op = NULL;
char a;
char In[81], Out[81];
int k = 0, l = 0;
std::cout << "Input form: " << std::endl;
std::cin >> In;
while (In[k] != '\0')
{
if (In[k] >= 'a' && In[k] <= 'z')
{
Out[l++] = In[k];
}
if (In[k] == '(')
{
Op == InStack(Op, In[k]);
}
if (In[k] == ')')
{
while ((Op->info) != '(') //ERROR HERE
{
Op = OutStack(Op, a);
if (!Op)
{
a = '\0';
}
Out[l++] = a;
}
t = Op;
Op = Op->next;
delete t;
}
if (In[k] == '+' || In[k] == '-' || In[k] == '*' || In[k] == '/')
{
while (Op != NULL && Prior(Op->info) >= Prior(In[k]))
{
Op = OutStack(Op, a);
Out[l++] = a;
}
Op = InStack(Op, In[k]);
}
k++;
}
while (Op != NULL)
{
Op = OutStack(Op, a);
Out[l++] = a;
}
Out[l] = '\0';
std::cout << "\nPolish: " << Out << std::endl;
std::cout << "\nRes = " << Result(Out) << std::endl;
}

get value of postfix experssion from number more than one digit

#include <iostream>
#include <string>
#include <stack>
using namespace std;
float postix_evalute(string expr)
{
stack<float> stk;
for (int x = 0; x < expr.length(); x++)
{
if (isdigit(expr[x]))
{
stk.push((expr[x] - '0'));
}
else
{
float val;
float op2 = stk.top();
stk.pop();
float op1 = stk.top();
stk.top();
switch (expr[x])
{
case '+':
val = op1 + op2;
break;
case '-':
val = op1 - op2;
break;
case '*':
val = op1 * op2;
break;
case '/':
val = op1 / op2;
break;
}
stk.push(val);
}
}
return stk.top();
}
int main()
{
string line;
cout << "The Value Of expression" << endl;
cin >> line;
cout << postix_evalute(line) << endl;
return 0;
}
When I enter the expression "213+" I get the output "4"; but I expect to get 24 (21+3).
What should I do to take operands with more than on digit?
You need a way to differentiate the tokens of your postfix expressions. For example, if the input is 213+, a parser would typically read that as 213 and +. For these simple expressions, you could separate the different tokens with whitespaces, as in 21 3 +. Then, having that input in a string, you could read each token with an input string stream.
float postix_evalute(std::string input)
{
std::stack<float> stk;
std::istringstream iss{input};
std::string token{};
while (not iss.eof())
{
iss >> token;
try
{
stk.push(std::stof(token));
}
catch (const std::invalid_argument& ex)
{
assert(stk.size() >= 2);
float op2 = stk.top(); stk.pop();
float op1 = stk.top(); stk.pop();
float val{};
if (token == "+") { val = op1 + op2; }
else if (token == "-") { val = op1 - op2; }
else if (token == "*") { val = op1 * op2; }
else if (token == "/") { val = op1 / op2; }
else { throw std::runtime_error{std::string{"unknown token: " + token}}; }
stk.push(val);
}
}
return stk.top();
}
Demo 1: using 21 3 + as an input.
Demo 2: using 21 3 # as an input.

Infix/Postfix evaluator terminating issue

I've got a few different functions that on their own work fine. Now I am trying to put them together into one file. My debugger is throwing segmentation faults in the infixToPostfix function.
When I watch the ns variable, it does not show anything getting assigned to it, but it prints out the postfix expression when I actually run the code. When ns passes into PostfixEvaulation, it runs to the top member function of TemplateStack and crashes with:
terminate called after throwing an instance of "std::string"
This only happens when I pass a string with an operator. When I pass a string of just numbers, everything runs fine,
but it still does not seem to call PostfixEvaluation.
#include <iostream>
#include <sstream>
#include <string>
#include <typeinfo>
using namespace std;
//Class Template Stack declaration
template <class T>
class TemplateStack {
public:
typedef T type;
TemplateStack()
{
max_size_ = 50;
TopOfStack = 0;
data_ = new T[max_size_];
} //Default Constructor taking no parameters
void push(T element)
{
if (TopOfStack == max_size_)
throw string("Stack's underlying storage is overflow");
TopOfStack++;
data_[TopOfStack] = element;
}
void pop() {
if (TopOfStack == -1)
throw string("Stack is empty");
TopOfStack--;
}
T top() {
if (TopOfStack == -1)
throw string("Stack is empty");
return data_[TopOfStack];
}
private:
int TopOfStack; //Generic data type for the top element of stack
size_t max_size_;
T* data_;
};
//Function to Evauluate the Postfix notation expresion
int PostfixEvaulation(string input){
//string input;
int operand1, operand2, result,number;
TemplateStack<char>operation;
stringstream temp;
int i=0;
while (i < input.length())
{
if (isdigit(input[i]))
{
operation.push(input[i]);
}
else
{
operand2 = operation.top();
temp << operation.top();
operation.pop();
operand1 = operation.top();
temp << operation.top();
operation.pop();
switch(operand1,operand2)
{
case '+': result=operand1 + operand2;
break;
case '-': result=operand1 - operand2;
break;
case '*': result=operand1 * operand2;
break;
case '/': result=operand1 / operand2;
break;
}
operation.push(result);
}
i++;
}
cout << "The result is: "<<temp.str()<<endl;
//cin.ignore(numeric_limits<streamsize>::max(), '\n');
return 0;
}
//Function to return precedence of operators
int prec(char c)
{
if(c == '^')
return 3;
else if(c == '*' || c == '/')
return 2;
else if(c == '+' || c == '-')
return 1;
else
return -1;
}
//Function: Convert Infix to Postfix
void infixToPostfix(string s)
{
TemplateStack<char> st;
st.push('N');
int l = s.length();
string ns;
for (int i = 0; i < l; i++) {
// If the scanned character is an operand, add it to output string.
if ((s[i] >= 'a' && s[i] <= 'z') || (s[i] >= 'A' && s[i] <= 'Z')) {
ns += s[i];
}
// If the scanned character is an ‘(‘, push it to the stack.
else if (s[i] == '(') {
st.push('(');
}
// If the scanned character is an ‘)’, pop and to output string from the stack
// until an ‘(‘ is encountered.
else if (s[i] == ')') {
while (st.top() != 'N' && st.top() != '(') {
char c = st.top();
st.pop();
ns += c;
}
if (st.top() == '(') {
char c = st.top();
st.pop();
}
}
//If an operator is scanned
else {
while (st.top() != 'N' && prec(s[i]) <= prec(st.top())) {
char c = st.top();
st.pop();
ns += c;
}
st.push(s[i]);
}
}
//Pop all the remaining elements from the stack
while (st.top() != 'N') {
char c = st.top();
st.pop();
ns += c;
}
cout << "Here is the ns variable: "<< ns << endl;
PostfixEvaulation(ns);//Call the PostFixEvaluationFunction with the ns (postfix notation) variab
}
//Function: User inputs Expression
void GetInput(){
string input;
cout << "Enter Infix Expression: ";
getline(cin, input);
infixToPostfix(input);
}
int main()
{
GetInput();
}

How to transmission parameters like string data type in c++

I'm trying to transmission parameters onto my function to excute
Here's my stack.h file
#ifndef stackarray_h
#define stackarray_h
#include<iostream>
#include<string>
using namespace std;
const int MAX_SIZE = 100;
typedef string Type;
class Stack{
private:
Type item[MAX_SIZE];
int top;
public:
Stack();
bool isEmpty()const;
void push(Type value);
void pop();
Type getTop();
};
Stack::Stack(){
top = -1;
}
bool Stack::isEmpty()const{
if (top == -1)
return true;
else
return false;
}
void Stack::push(Type value){
item[++top] = value;
}
void Stack::pop(){
if (top != -1){
top = top - 1;
}
}
Type Stack::getTop(){
return item[top];
}
#endif
Here's my source.cpp file. My problem that i can't transmission parameters string into stack to my push function.
#include<iostream>
using namespace std;
#include<string>
#include<fstream>
#include"stack.h"
void readFile(char* file,string &str);
void convertFromInfixToPostfix(string &str);
int evaluatingPostfix(string str);
int convert(int value);
string convertToString(int value);
int main(){
string str;
readFile("Text.txt",str);
cout<<str<<endl;
convertFromInfixToPostfix(str);
cout << "Output: ";
cout << str << endl;
cout << "Result: ";
cout << evaluatingPostfix(str) << endl;
return 0;
}
void readFile(char* file,string &str){
ifstream read(file);
if (!read.is_open()){
cout << "Error!.File wasn't opened." << endl;
}
else
{
getline(read, str);
}
read.close();
}
void convertFromInfixToPostfix(string &str){
Stack _stack;
string output="";
int i = 0;
while (i < str.length()){
if (str[i] == '(' || str[i] == '+' || str[i] == '-'
|| str[i] == '*' || str[i] == '/' || str[i] == '%'){
_stack.push(str[i]);
}
else {
//excute character )
if (str[i] == ')'){
while (!_stack.isEmpty()){
char top = _stack.getTop();
output += top;
_stack.pop();
}
}else
//excute character digit
output = output + str[i];
}
// excute end of string
if (_stack.getTop() == '('){
_stack.pop();
}
i++;
}
str = output;
}
int evaluatingPostfix(string str){
int result;
Stack _stack;
int op1, op2;
int i = 0;
int index;
string temp;
char next_ch;
while (i < str.length()){
next_ch = str[i];
if (next_ch == '+' || next_ch == '-'
|| next_ch == '*' || next_ch == '/'
){
//excute operator
op1 = _stack.getTop();
_stack.pop();
// convert op1 to integer
op1 = convert(op1);
op2 = _stack.getTop();
_stack.pop();
// convert op2 to integer
op2 = convert(op2);
if (next_ch == '+'){
index = op2 + op1;
// convert index from integer to char
temp = convertToString(index);
_stack.push(temp);
}
if (next_ch == '-'){
index = op2 - op1;
// convert index from integer to char
temp = convertToString(index);
_stack.push(temp);
}
if (next_ch == '*'){
index = op2 * op1;
// convert index from integer to char
temp = convertToString(index);
_stack.push(temp);
}
if (next_ch == '/'){
index = op2 / op1;
// convert index from integer to char
temp = convertToString(index);
_stack.push(temp);
}
}
else {
// excute integer
_stack.push(next_ch);
}
i++;
}
// push the result onto the _stack
result = _stack.getTop();
// _stack is empty
_stack.pop();
return result;
}
int convert(int value){
int result;
result = value - 48;
return result;
}
string convertToString(int value){
string result ;
int n = value;
do{
n = n % 10;
result = result + (char)(n + 48);
} while (n>0);
return result;
}
There are error:
Error 4 error C2664: 'void Stack::push(stackItemType)' : cannot
convert argument 1 from 'std::string' to 'stackItemType'
At line _stack.push(temp);
I'm sorry because my english isn't good.

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;
}