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
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;
}
#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.
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();
}
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.
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;
}