converting infix to postfix (assignment operator included) using c++ - c++

I was trying to convert to an infix expression to postfix in c++. I have done coding with simple operators /,*,+,- but I am confused about the logic for assignment operator(=). I know it must be given the lowest precedence but for input like A=B=4 or A=(B=2)*2, how can I decide the precedence. My code is written below. (without implementation for assignment operator).
#include <iostream>
#include <stack>
#include <string>
using namespace std;
// Simply determine if character is one of the four standard operators.
bool isOperator(char character) {
if (character == '+' || character == '-' || character == '*' || character == '/' || character=='=') {
return true;
}
return false;
}
// If the character is not an operator or a parenthesis, then it is assumed to be an operand.
bool isOperand(char character) {
if (!isOperator(character) && character != '(' && character != ')') {
return true;
}
return false;
}
// Compare operator precedence of main operators.
// Return 0 if equal, -1 if op2 is less than op1, and 1 if op2 is greater than op1.
int compareOperators(char op1, char op2) {
if ((op1 == '*' || op1 == '/') && (op2 == '+' || op2 == '-')) { return -1; }
else if ((op1 == '+' || op1 == '-') && (op2 == '*' || op2 == '/')) { return 1; }
return 0;
}
int main()
{
// Empty character stack and blank postfix string.
stack<char> opStack;
string postFixString = "";
char input[100];
// Collect input
cout << "Enter an expression: ";
cin >> input;
// Get a pointer to our character array.
char *cPtr = input;
// Loop through the array (one character at a time) until we reach the end of the string.
while (*cPtr != '\0') {
// If operand, simply add it to our postfix string.
// If it is an operator, pop operators off our stack until it is empty, an open parenthesis or an operator with less than or equal precedence.
if (isOperand(*cPtr)) { postFixString += *cPtr; }
else if (isOperator(*cPtr)) {
while (!opStack.empty() && opStack.top() != '(' && compareOperators(opStack.top(), *cPtr) <= 0) {
postFixString += opStack.top();
opStack.pop();
}
opStack.push(*cPtr);
}
// Simply push all open parenthesis onto our stack
// When we reach a closing one, start popping off operators until we run into the opening parenthesis.
else if (*cPtr == '(') { opStack.push(*cPtr); }
else if (*cPtr == ')') {
while (!opStack.empty()) {
if (opStack.top() == '(') { opStack.pop(); break; }
postFixString += opStack.top();
opStack.pop();
}
}
// Advance our pointer to next character in string.
cPtr++;
}
// After the input expression has been ran through, if there is any remaining operators left on the stack
// pop them off and put them onto the postfix string.
while (!opStack.empty()) {
postFixString += opStack.top();
opStack.pop();
}
// Show the postfix string at the end.
cout << "Postfix is: " << postFixString << endl;
return 0;
}

Try giving it the same precedence as the operands, and see what you get:
// Simply determine if character is one of the four standard operators.
bool isOperator(char character) {
if (character == '+' || character == '-' || character == '*' || character == '/') {
//|| character=='='
return true;
}
return false;
}
// If the character is not an operator or a parenthesis, then it is assumed to be an operand.
bool isOperand(char character) {
//for =, treat it wth the same rules as the operands; push to output
if (character == '='){
return true;
}
if (!isOperator(character) && character != '(' && character != ')') {
return true;
}
return false;
}

Related

Closing Parenthesis Recognition and Precedence of Operators In Infix to Postfix Stack Program C++

I have an assignment in my Data Structures course where the C++ program calls a function named infixToPostfix, which reads an infix expression from standard input and writes the equivalent postfix expression to standard output.
However, I'm having difficulties with two logic errors at the moment:
My closing parenthesis isn't getting recognized in my program. When I attempt to pop the ')' out of the stack, it causes a segmentation error, crashing the program.
The precedence of operators during the conversion isn't in proper order. I'm guessing it's because my program is recognizing the operators to where each operator pops the previous one out of the stack, no matter what their precedence is.
My current code:
#include <iostream>
#include <stack> // Library used to store a stack of characters
#include <string>
using namespace std;
bool isOperator(char ch) // Checks if character is operator
{
if(ch == '^' || ch == '*' || ch == '/' || ch == '+' || ch == '-')
{
return true;
}
else
{
return false;
}
}
bool isOperand(char ch) // Checks if character is operand
{
// If not an operator or a parenthesis, then assume operand
if(!isOperator(ch) && ch != '(' && ch != ')')
{
return true;
}
else
{
return false;
}
}
// Retrieves weight of operators as per precedence
// Higher weight = higher precedence in operators
// Returns 0 for non-operators
int getWeight(char ch)
{
switch(ch) {
case '^': // exponents
return 3;
case '/':
case '*':
return 2;
case '+':
case '-':
return 1;
default :
return 0;
}
}
string infixToPostfix(string expression)
{
// Declare stack
stack<char> op_stack;
// Initialize postfix as empty string
string postfix = "";
for(int i = 0; i < expression.length(); i++)
{
// Scanning each character from left.
// If character is a delimiter, move on.
if(expression[i] == ' ' || expression[i] == ',')
{
continue;
}
// If character is operator, pop two elements from stack,
// perform operation, and push result back.
else if(isOperator(expression[i]))
{
while(!op_stack.empty() && op_stack.top() != \
getWeight(op_stack.top()) <= getWeight(expression[i]))
{
postfix += op_stack.top();
op_stack.pop();
}
op_stack.push(expression[i]);
}
// Else if character is operand
else if(isOperand(expression[i]))
{
postfix += expression[i];
}
// Parenthesis
else if(expression[i] == '(')
{
// Push operator onto stack if empty
op_stack.push(expression[i]);
}
else if(expression[i] == ')')
{
while(!op_stack.empty() && op_stack.top() != '(')
{
postfix += op_stack.top();
op_stack.pop();
}
//op_stack.pop();
}
}
while(!op_stack.empty())
{
postfix += op_stack.top();
op_stack.pop();
}
return postfix;
}
int main() {
string expression;
cout << "Enter Infix Expression: \n";
getline(cin, expression);
// Displays inputted infix string and calculated
// Postfix string
cout << "Infix Expression: " << expression << '\n';
cout << "Postfix Expression: " << infixToPostfix(expression) << '\n';
return 0;
}
Sample output:
Enter Infix Expression:
(6+2)*5^8/4
Infix Expression: (6+2)*5^8/4
Postfix Expression: 6(2+5*8^4/
Where the correct postfix should be 62+58^*4/
Any help would be greatly appreciated.

What '$' means when scaning if char in strings are certain symbols?

im studying c++, and im stuck on understanding certain line of code.
bool IsOperator(char C)
{
if(C == '+' || C == '-' || C == '*' || C == '/' || C== '$')
return true;
return false;
}
The program im trying to understand scans if the char in string is operator. If yes, get him a number. Inflix to postflix is the problem here.
int IsRightAssociative(char op)
{
if(op == '$') return true;
return false;
}
Here is what i cant understand, where the program finds the '$' char if i write ((3+2)*3-5)*2??
I will attach the whole code for better understanding
#include<iostream>
#include<stack>
#include<string>
using namespace std;
// Function to convert Infix expression to postfix
string InfixToPostfix(string expression);
// Function to verify whether an operator has higher precedence over other
int HasHigherPrecedence(char operator1, char operator2);
// Function to verify whether a character is operator symbol or not.
bool IsOperator(char C);
// Function to verify whether a character is alphanumeric chanaract (letter or numeric digit) or not.
bool IsOperand(char C);
int main()
{
string expression;
cout<<"Enter Infix Expression \n";
getline(cin,expression);
string postfix = InfixToPostfix(expression);
cout<<"Output = "<<postfix<<"\n";
}
// Function to evaluate Postfix expression and return output
string InfixToPostfix(string expression)
{
// Declaring a Stack from Standard template library in C++.
stack<char> S;
string postfix = ""; // Initialize postfix as empty string.
for(int i = 0;i< expression.length();i++) {
// Scanning each character from left.
// If character is a delimitter, move on.
if(expression[i] == ' ' || expression[i] == ',') continue;
// If character is operator, pop two elements from stack, perform operation and push the result back.
else if(IsOperator(expression[i]))
{
while(!S.empty() && S.top() != '(' && HasHigherPrecedence(S.top(),expression[i]))
{
postfix+= S.top();
S.pop();
}
S.push(expression[i]);
}
// Else if character is an operand
else if(IsOperand(expression[i]))
{
postfix +=expression[i];
}
else if (expression[i] == '(')
{
S.push(expression[i]);
}
else if(expression[i] == ')')
{
while(!S.empty() && S.top() != '(') {
postfix += S.top();
S.pop();
}
S.pop();
}
}
while(!S.empty()) {
postfix += S.top();
S.pop();
}
return postfix;
}
// Function to verify whether a character is english letter or numeric digit.
// We are assuming in this solution that operand will be a single character
bool IsOperand(char C)
{
if(C >= '0' && C <= '9') return true;
if(C >= 'a' && C <= 'z') return true;
if(C >= 'A' && C <= 'Z') return true;
return false;
}
// Function to verify whether a character is operator symbol or not.
bool IsOperator(char C)
{
if(C == '+' || C == '-' || C == '*' || C == '/' || C== '$')
return true;
return false;
}
// Function to verify whether an operator is right associative or not.
int IsRightAssociative(char op)
{
if(op == '$') return true;
return false;
}
// Function to get weight of an operator. An operator with higher weight will have higher precedence.
int GetOperatorWeight(char op)
{
int weight = -1;
switch(op)
{
case '+':
case '-':
weight = 1;
case '*':
case '/':
weight = 2;
case '$':
weight = 3;
}
return weight;
}
// Function to perform an operation and return output.
int 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.
// 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;
}
So if anyone can help i will be very glad :(.

infix to postfix with logical operators - code error

i m trying to Write a function string InfixToPostfix(string infixExpr) that takes as input an expression string in infix notation, and returns a string containing the postfix notation for that expression. The infix notation can have
parenthesis. The program needs to handle these operators ∗,/, %, +, − , <, <=, >=, >, ==, ! =,&&,|| (binary operators only)
Here is the code i am trying.. its running perfect with parenthsis but gives slight wrong output without parenthesis. e.g if input is A+B/C the output should be ABC/+, but instead it gives AB+C/ . please help me spot the error. Thanks
#include<iostream>
#include<stack>
#include<string>
using namespace std;
// Function to convert Infix expression to postfix
string InfixToPostfix(string expression);
// Function to verify whether an operator has higher precedence over other
int HasHigherPrecedence(string operator1, string operator2);
// Function to verify whether a character is operator symbol or not.
bool IsOperator(string C);
// Function to verify whether a character is alphanumeric character (letter) or not.
bool IsOperand(string C);
int GetOperatorWeight(string opt);
bool IsDoubleOperator(char c1, char c2);
int main()
{
string expression;
cout<<"Enter Infix Expression \n";
getline(cin,expression);
string postfix = InfixToPostfix(expression);
cout<<"Output = "<<postfix<<"\n";
return 0;
}
// Function to evaluate Postfix expression and return output
string InfixToPostfix(string expression)
{
// Declaring a Stack from Standard template library in C++.
stack<string> S;
string postfix = ""; // Initialize postfix as empty string.
for(int i = 0;i< expression.length();i++) {
string ex="";
ex+=expression[i];
// Scanning each character from left.
// If character is a delimitter, move on.
if(ex == " " || ex == ",") continue;
// If character is operator, pop two elements from stack, perform operation and push the result back.
else if(IsOperator(ex))
{
while(!S.empty() && S.top() != "(" && HasHigherPrecedence(S.top(),ex))
{
postfix+= S.top();
S.pop();
}
S.push(ex);
}
// Else if character is an operand
else if(IsOperand(ex))
{
postfix +=ex;
}
else if (ex == "(")
{
S.push(ex);
}
else if(ex == ")")
{
while(!S.empty() && S.top() != "(") {
postfix += S.top();
S.pop();
}
S.pop();
}
else if (IsDoubleOperator(expression[i], expression[i+1]))
{
string db="";
string f="";
db=+expression[i];
f=+expression[i+1];
db=db+f;
while(!S.empty() && S.top() != "(" && HasHigherPrecedence(S.top(),db))
{
postfix+= S.top();
S.pop();
}
S.push(db);
i++;
}
}
while(!S.empty()) {
postfix += S.top();
S.pop();
}
return postfix;
}
// Function to verify whether a character is english letter or numeric digit.
// We are assuming in this solution that operand will be a single character
bool IsOperand(string C)
{
if(C >= "A" && C <= "Z") return true;
return false;
}
// Function to verify whether a character is operator symbol or not.
bool IsOperator(string C)
{
if(C == "+" || C == "-" || C == "*" || C == "/" || C== "%")
return true;
return false;
}
// Function to get weight of an operator. An operator with higher weight will have higher precedence.
int GetOperatorWeight(string op)
{
int weight = -1;
if(op=="&&"|| op=="||")
weight = 1;
if(op=="=="|| op=="!=")
weight = 2;
if(op=="<"|| op==">"|| op=="<="|| op==">=")
weight = 3;
if(op=="+"|| op=="-")
weight = 4;
if(op=="/"|| op=="%"|| op=="/")
weight = 5;
return weight;
}
// Function to perform an operation and return output.
int HasHigherPrecedence(string op1, string op2)
{
int op1Weight = GetOperatorWeight(op1);
int op2Weight = GetOperatorWeight(op2);
// If operators have equal precedence, return true if they are left associative.
// return false, if right associative.
// if operator is left-associative, left one should be given priority.
if (op1Weight > op2Weight)
return op1Weight;
else
return op2Weight;
}
bool IsDoubleOperator( char c1, char c2)
{
string db="";
string f="";
db=+c1;
f=+c2;
db=db+f;
if (db=="&&" ||db=="||" || db==">=" || db=="<=" || db=="!=" ||db=="==")
{
//cout<<db;
return true;
}
return false;
}
HasHigherPrecedence(op1, op2) is expected to return non-zero when op1 has a higher precedence (A.K.A. weight) than op2 and zero otherwise. However it returns the maximum of the two ops' weights, which is usually nonzero. You just need to change the function so it returns:
return op1Weight > op2Weight;
Which will be 1 when true and zero when false. This should fix your operator shunting.

Convert from an infix expression to postfix (C++) using Stacks

My lecturer gave me an assignment to create a program to convert and infix expression to postfix using Stacks. I've made the stack classes and some functions to read the infix expression.
But this one function, called convertToPostfix(char * const inFix, char * const postFix) which is responsible to convert the inFix expression in the array inFix to the post fix expression in the array postFix using stacks, is not doing what it suppose to do. Can you guys help me out and tell me what I'm doing wrong?
The following is code where the functions to convert from inFix to postFix is and convertToPostfix(char * const inFix, char * const postFix) is what I need help fixing:
void ArithmeticExpression::inputAndConvertToPostfix()
{
char inputChar; //declaring inputChar
int i = 0; //inizalize i to 0
cout << "Enter the Arithmetic Expression(No Spaces): ";
while( ( inputChar = static_cast<char>( cin.get() ) ) != '\n' )
{
if (i >= MAXSIZE) break; //exits program if i is greater than or equal to 100
if(isdigit(inputChar) || isOperator(inputChar))
{
inFix[i] = inputChar; //copies each char to inFix array
cout << inFix[i] << endl;
}
else
cout << "You entered an invalid Arithmetic Expression\n\n" ;
}
// increment i;
i++;
convertToPostfix(inFix, postFix);
}
bool ArithmeticExpression::isOperator(char currentChar)
{
if(currentChar == '+')
return true;
else if(currentChar == '-')
return true;
else if(currentChar == '*')
return true;
else if(currentChar == '/')
return true;
else if(currentChar == '^')
return true;
else if(currentChar == '%')
return true;
else
return false;
}
bool ArithmeticExpression::precedence(char operator1, char operator2)
{
if ( operator1 == '^' )
return true;
else if ( operator2 == '^' )
return false;
else if ( operator1 == '*' || operator1 == '/' )
return true;
else if ( operator1 == '+' || operator1 == '-' )
if ( operator2 == '*' || operator2 == '/' )
return false;
else
return true;
return false;
}
void ArithmeticExpression::convertToPostfix(char * const inFix, char * const postFix)
{
Stack2<char> stack;
const char lp = '(';
stack.push(lp); //Push a left parenthesis ‘(‘ onto the stack.
strcat(inFix,")");//Appends a right parenthesis ‘)’ to the end of infix.
// int i = 0;
int j = 0;
if(!stack.isEmpty())
{
for(int i = 0;i < 100;){
if(isdigit(inFix[i]))
{
postFix[j] = inFix[i];
cout << "This is Post Fix for the first If: " << postFix[j] << endl;
i++;
j++;
}
if(inFix[i] == '(')
{
stack.push(inFix[i]);
cout << "The InFix was a (" << endl;
i++;
//j++;
}
if(isOperator(inFix[i]))
{
char operator1 = inFix[i];
cout << "CUrrent inFix is a operator" << endl;
if(isOperator(stack.getTopPtr()->getData()))
{
cout << "The stack top ptr is a operator1" << endl;
char operator2 = stack.getTopPtr()->getData();
if(precedence(operator1,operator2))
{
//if(isOperator(stack.getTopPtr()->getData())){
cout << "The stack top ptr is a operato2" << endl;
postFix[j] = stack.pop();
cout << "this is post fix " << postFix[j] << endl;
i++;
j++;
// }
}
}
else
stack.push(inFix[i]);
// cout << "Top Ptr is a: "<< stack.getTopPtr()->getData() << endl;
}
for(int r = 0;r != '\0';r++)
cout << postFix[r] << " ";
if(inFix[i] == ')')
{
while(stack.stackTop()!= '(')
{
postFix[j] = stack.pop();
i++;
j++;
}
stack.pop();
}
}
}
}
Note the function convertToPostfix was made using this algorithm:
Push a left parenthesis ‘(‘ onto the stack.
Append a right parenthesis ‘)’ to the end of infix.
While the stack is not empty, read infix from left to right and do the following:
If the current character in infix is a digit, copy it to the next element of postfix.
If the current character in infix is a left parenthesis, push it onto the stack.
If the current character in infix is an operator,
Pop operator(s) (if there are any) at the top of the stack while they have equal or higher precedence than the current operator, and insert the popped operators in postfix.
Push the current character in infix onto the stack.
If the current character in infix is a right parenthesis
Pop operators from the top of the stack and insert them in postfix until a left parenthesis is at the top of the stack.
Pop (and discard) the left parenthesis from the stack.
This is basically a comment to the answer from Yuushi.
The outer while(!stack.empty()) loop is wrong. just remove it. (keep the loop body ofc). At the end of the function, check that the stack is empty, else the expression had syntax errors.
As Yuushi already said the precedence function looks bogus. First you should give the parameters better names: one is the operator to the left, and the other to the right. (Right now you call it precedence(rightOp, leftOp)). Then you should document what the result means - right now you return true if a rOp b lOp c == (a rOp b) lOp c (yes, the operator order doesn't match what you call - "+" and "-" are not the same in both orders for example).
If you find a new operator you need to loop over the old operators on the stack, for example after reading a - b * c your output is a b c and the stack is [- *]. now you read a +, and you need to pop both operators, resulting in a b c * -. I.e., the input a - b * c + d should result in a b c * - d +
Update: appended complete solution (based on Yuushi's answer):
bool isOperator(char currentChar)
{
switch (currentChar) {
case '+':
case '-':
case '*':
case '/':
case '^':
case '%':
return true;
default:
return false;
}
}
// returns whether a `lOp` b `rOp` c == (a `lOp` b) `rOp` c
bool precedence(char leftOperator, char rightOperator)
{
if ( leftOperator == '^' ) {
return true;
} else if ( rightOperator == '^' ) {
return false;
} else if ( leftOperator == '*' || leftOperator == '/' || leftOperator == '%' ) {
return true;
} else if ( rightOperator == '*' || rightOperator == '/' || rightOperator == '%' ) {
return false;
}
return true;
}
#include <stdexcept>
#include <cctype>
#include <sstream>
#include <stack>
std::string convertToPostfix(const std::string& infix)
{
std::stringstream postfix; // Our return string
std::stack<char> stack;
stack.push('('); // Push a left parenthesis ‘(‘ onto the stack.
for(std::size_t i = 0, l = infix.size(); i < l; ++i) {
const char current = infix[i];
if (isspace(current)) {
// ignore
}
// If it's a digit or '.' or a letter ("variables"), add it to the output
else if(isalnum(current) || '.' == current) {
postfix << current;
}
else if('(' == current) {
stack.push(current);
}
else if(isOperator(current)) {
char rightOperator = current;
while(!stack.empty() && isOperator(stack.top()) && precedence(stack.top(), rightOperator)) {
postfix << ' ' << stack.top();
stack.pop();
}
postfix << ' ';
stack.push(rightOperator);
}
// We've hit a right parens
else if(')' == current) {
// While top of stack is not a left parens
while(!stack.empty() && '(' != stack.top()) {
postfix << ' ' << stack.top();
stack.pop();
}
if (stack.empty()) {
throw std::runtime_error("missing left paren");
}
// Discard the left paren
stack.pop();
postfix << ' ';
} else {
throw std::runtime_error("invalid input character");
}
}
// Started with a left paren, now close it:
// While top of stack is not a left paren
while(!stack.empty() && '(' != stack.top()) {
postfix << ' ' << stack.top();
stack.pop();
}
if (stack.empty()) {
throw std::runtime_error("missing left paren");
}
// Discard the left paren
stack.pop();
// all open parens should be closed now -> empty stack
if (!stack.empty()) {
throw std::runtime_error("missing right paren");
}
return postfix.str();
}
#include <iostream>
#include <string>
int main()
{
for (;;) {
if (!std::cout.good()) break;
std::cout << "Enter the Arithmetic Expression: ";
std::string infix;
std::getline(std::cin, infix);
if (infix.empty()) break;
std::cout << "Postfix: '" << convertToPostfix(infix) << "'\n";
}
return 0;
}
So there are a number of problems with your code. I'll post what (should be) a corrected solution, which has copious comments to explain what's happening and where you've made mistakes. A few things up front:
I'll use std::string instead of char * because it makes things much cleaner, and honestly, you should be using it in C++ unless you have a very good reason not to (such as interoperability with a C library). This version also returns a string instead of taking a char * as a parameter.
I'm using the stack from the standard library, <stack>, which is slightly different to your home-rolled one. top() shows you the next element without removing it from the stack, and pop() returns void, but removes the top element from the stack.
It's a free function, not part of a class, but that should be easy to modify - it's simply easier for me to test this way.
I'm not convinced your operator precedence tables are correct, however, I'll let you double check that.
#include <stack>
#include <cctype>
#include <iostream>
std::string convertToPostfix(std::string& infix)
{
std::string postfix; //Our return string
std::stack<char> stack;
stack.push('('); //Push a left parenthesis ‘(‘ onto the stack.
infix.push_back(')');
//We know we need to process every element in the string,
//so let's do that instead of having to worry about
//hardcoded numbers and i, j indecies
for(std::size_t i = 0; i < infix.size(); ++i) {
//If it's a digit, add it to the output
//Also, if it's a space, add it to the output
//this makes it look a bit nicer
if(isdigit(infix[i]) || isspace(infix[i])) {
postfix.push_back(infix[i]);
}
//Already iterating over i, so
//don't need to worry about i++
//Also, these options are all mutually exclusive,
//so they should be else if instead of if.
//(Mutually exclusive in that if something is a digit,
//it can't be a parens or an operator or anything else).
else if(infix[i] == '(') {
stack.push(infix[i]);
}
//This is farily similar to your code, but cleaned up.
//With strings we can simply push_back instead of having
//to worry about incrementing some counter.
else if(isOperator(infix[i]))
{
char operator1 = infix[i];
if(isOperator(stack.top())) {
while(!stack.empty() && precedence(operator1,stack.top())) {
postfix.push_back(stack.top());
stack.pop();
}
}
//This shouldn't be in an else - we always want to push the
//operator onto the stack
stack.push(operator1);
}
//We've hit a right parens - Why you had a for loop
//here originally I don't know
else if(infix[i] == ')') {
//While top of stack is not a right parens
while(stack.top() != '(') {
//Insert into postfix and pop the stack
postfix.push_back(stack.top());
stack.pop();
}
// Discard the left parens - you'd forgotten to do this
stack.pop();
}
}
//Remove any remaining operators from the stack
while(!stack.empty()) {
postfix.push_back(stack.top());
stack.pop();
}
}
Here's mine using C with multiple digits evaluation.
#include <stdio.h>
#include <math.h>
#define MAX 50
void push(char[],char);
void in_push(double[], double);
int pop();
int prec(char);
double eval(char[],int,double[]);
int top = 0;
void main() {
double eval_stack[MAX];
int op_count=0;
char stack[MAX], exps[MAX], symbols[MAX];
int i=0,j=0,len,check;
while((symbols[i]=getchar())!='\n') {
if(symbols[i]!=' ' || symbols[i]!='\t') {
if(symbols[i]=='+' || symbols[i]=='-' || symbols[i]=='/' || symbols[i]=='*' || symbols[i]=='^')
op_count++;
i++;
}
}
symbols[i]='#';
symbols[++i]='\0';
len = strlen(symbols);
stack[top] = '#';
for(i=0; i<=len; i++) {
if(symbols[i]>='a' && symbols[i]<='z') {
exps[j]=symbols[i];
j++;
}
switch(symbols[i]) {
case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9':
//if(symbols[i]>='a' && symbols[i]<='z') {
exps[j]=symbols[i];
j++;
break;
case '+': case '-': case '*': case '/': case '^':
exps[j++] = ' ';
while(prec(symbols[i]) <= prec(stack[top])) {
exps[j] = stack[top];
pop();
//printf("\n\t\t%d\t\t%d\n", top,j);
j++;
}
if(prec(symbols[i]) > prec(stack[top])) {
push(stack,symbols[i]);
}
break;
case '(':
push(stack,symbols[i]);
break;
case ')':
while(stack[top]!='(') {
exps[j] = stack[top];
pop();
j++;
}
pop();
break;
case '#':
exps[j++] = ' ';
while(stack[top]!='#') {
exps[j] = stack[top];
pop();
j++;
}
pop();
break;
}
}
exps[j]='\0';
printf("Postfix: %s", exps);
for(i=0; i<j; i++)
if(exps[i]=='a')
check = 1;
if(check!=1)
printf("\nSolution: %.1f", eval(exps,j,eval_stack));
}
double eval(char exps[],int exps_len,double eval_stack[]) {
int i; int len=exps_len,temp;
double in_temp[MAX],t;
int count,power,j,in_count;
count=power=j=t=in_count=0;
double result;
for(i=0; i<len; i++) {
switch(exps[i]) {
case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9':
in_temp[i] = exps[i]-'0';
j=i+1;
while(exps[j]>='0' && exps[j]<='9') {
in_temp[j] = exps[j]-'0';
j++; // 2
}
count = i; // 3
while(in_temp[count]<='0' && in_temp[count]<='9') {
power = (j-count)-1;
t = t + in_temp[count]*(pow(10,power));
power--;
count++;
}
in_push(eval_stack,t);
i=j-1;
t=0;
break;
case '+':
temp = pop();
pop();
result = eval_stack[temp] + eval_stack[temp+1];
in_push(eval_stack,result);
break;
case '-':
temp = pop();
pop();
result = eval_stack[temp] - eval_stack[temp+1];
in_push(eval_stack,result);
break;
case '*':
temp = pop();
pop();
result = eval_stack[temp] * eval_stack[temp+1];
in_push(eval_stack,result);
break;
case '/':
temp = pop();
pop();
result = eval_stack[temp] / eval_stack[temp+1];
in_push(eval_stack,result);
break;
case '^':
temp = pop();
pop();
result = pow(eval_stack[temp],eval_stack[temp+1]);
in_push(eval_stack,result);
break;
}
}
return eval_stack[top];
}
int prec(char a) {
if(a=='^')
return 3;
else if(a=='*' || a=='/' || a=='%')
return 2;
else if(a=='+' || a=='-')
return 1;
else if(a=='(')
return 0;
else
return -1;
}
void push(char stack[], char ele) {
if(top>=MAX) {
printf("\nStack Overflow");
exit(1);
}
stack[++top] = ele;
}
void in_push(double stack[], double ele) {
if(top>=MAX) {
printf("\nStack Overflow");
exit(1);
}
stack[++top] = ele;
}
int pop() {
if(top<0) {
printf("\nStack Underflow");
exit(1);
}
top = top - 1;
return top;
}
This is my implementation of converting infix to postfix expression
//Infix to Postfix conversion
#include <bits/stdc++.h>
using namespace std;
bool isoperator(char c) // function to check if the character is an operator
{
if(c=='+'||c=='-'||c=='*'||c=='/'||c=='^')
return true;
else
return false;
}
int precedence(char c) // function to given the precedence of the operators
{
if(c == '^')
return 3;
else if(c == '*' || c == '/')
return 2;
else if(c == '+' || c == '-')
return 1;
else
return -1;
}
void infixToPostfix(string s) // funtion to convert infix to postfix
{
stack<char>st;
string postfix;
for(int i=0;i<s.length();i++)
{
if((s[i]>='a'&&s[i]<='z')||(s[i]>='A'&&s[i]<='Z')) // if the given character is alphabet add it to the postfix string
postfix+=s[i];
else if(s[i]=='(') // if the given character is "(" add it to the postfix string
st.push('(');
else if(s[i]==')') // if we find a closing bracket we pop everything from stack till opening bracket and add it to postfix string
{
while(st.top()=='(' && !st.empty())
{
postfix+=st.top();
st.pop();
}
if(st.top()=='(') // popping the opening bracket
st.pop();
}
else if(isoperator(s[i])) // if we find a operator
{
if(st.empty()) // if stack is empty add it to the stack
st.push(s[i]);
else
{
if(precedence(s[i])>precedence(st.top())) // if operator precedence is grater push it in stack
st.push(s[i]);
else if((precedence(s[i])==precedence(st.top()))&&(s[i]=='^')) // unique case for ^ operator
st.push(s[i]);
else
{
while((!st.empty())&&(precedence(s[i])<=precedence(st.top()))) // if precedence of st.top() is greater than s[i] adding it the postfix string
{
postfix+=st.top();
st.pop();
}
st.push(s[i]); // pushing s[i] in the stack
}
}
}
}
while(!st.empty()) // popping the remaining items from the stack and adding it to the postfix string
{
postfix+=st.top();
st.pop();
}
cout<<postfix<<endl; // printing the postfix string
}
int main()
{
ios_base::sync_with_stdio(false);
cin.tie(NULL);
string s;
cin>>s;
infixToPostfix(s);
return 0;
}
Example:
Input: a+b*(c^d-e)^(f+g*h)-i
Output: abcd^efgh*+i-(^-(*+
ps: If you find any mistakes, comment below :)
C++ implementation is given below:
void infix2postfix(string s)
{
stack<char>st;
for(int i=0; i<s.length(); i++)
{
if(isdigit(s[i]) || isalpha(s[i])) cout<<s[i];
else if( s[i]==')' )
{
while(st.top()!='(')
{
cout<<st.top();
st.pop();
}
st.pop();
}
else st.push(s[i]);
}
}
Operator Precedence is the problem in this case. The correct operator precedence in descending order is:
mul, div, mod << *, /, % >>
add, sub << +, - >>
XOR << ^ >>
In the question above consider the precedence function
bool ArithmeticExpression::precedence(char operator1, char operator2)
{
if ( operator1 == '^' )
return true;
else if ( operator2 == '^' )
return false;
else if ( operator1 == '*' || operator1 == '/' )
return true;
else if ( operator1 == '+' || operator1 == '-' )
if ( operator2 == '*' || operator2 == '/' )
return false;
else
return true;
return false;
}
for each value in operator1 corresponding value of operator2 should be checked for precedence, according to OPERATOR PRECEDENCE TABLE mentioned above. Do not return any value without proper comparison.

a code for infix to postfix conversion

I have written a code for infix to postfix conversion,This piece of code is not encountering any kind of compile time error but after taking the input infix expression it is giving some runtime errors which i am unable to understand these errors are something related to string as the message says.
#include<iostream>
#include<string>
#define N 50
using namespace std;
class stack
{
private:
char arr[N];
int tos;
public:
void push(char p)
{
if (tos != N)
arr[++tos] = p;
else
cout << "stack full";
}
char pop()
{
if (tos == -1)
cout << "stack Empty";
else
return (arr[tos--]);
}
bool isempty()
{
if (tos == -1)
return (true);
else
return (false);
}
char top()
{
return arr[tos];
}
stack()
{
tos = -1;
}
};
int pres(char sym)
{
if (sym == '^')
return 3;
else if (sym == '*' || '/')
return 2;
else if (sym == '+' || '-')
return 1;
else if (sym == '(')
return 0;
}
bool isoperator(char op)
{
if (op=='+' || op=='-' || op=='/' || op=='*' || op=='^')
return true;
else
return false;
}
int main()
{
string infix, postfix;
stack s;
int in=0;
int post=0;
cout << "Enter an infix expression: ";
cin >> infix;
s.push('(');
infix.append(")");
char temp;
while (!(s.isempty()))
{
if (isdigit(infix[in]))
postfix[post++] = infix[in];
else if (infix[in] == '(')
s.push(infix[in]);
else if (infix[in] == ')')
{
while (1)
{
temp = s.pop();
if (temp == '(')
break;
else
postfix[post] = infix[in];
}
}
else if (isoperator(infix[in]))
{
while (pres(s.top()) >= pres(infix[in]))
postfix[post++] = s.pop();
s.push(infix[in]);
}
in++;
}
cout << "Postfix expression is: " << postfix;
system("pause");
}
I m unable to get what's wrong with it. Can any one help??
I found the following logical errors in your code:
the result string postfix is empty at the beginning, but you're writing to single character positions using postfix[post++]=. This is not valid and is propably causing the "string related" errors. You should only use postfix.push_back() to add characters to the output string.
In the first inner while loop (while(1)) the last statement should read
postfix.push_back(temp);
since you want to append the operators from the stack to the output.
Your code falsely accept input with unbalanced additional closing parents like "1+4)". Personally, I would put the input position as outer loop condition and verify that the stack is empty after the loop (and check for empty stack in the pop() function) for detecting input errors.
The biggest error is in his pres() function, it should be:
else if (sym == '*' || sym == '/')
else if (sym == '+' || sym == '-')
I have noticed some of the errors mentioned by MartinStettner.