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.
Related
I'm currently trying to get this postfix expression eval to work but I believe within the int EvaluatePostfix function I'm using stackPtr->peek() incorrectly because whenever I try and get the top value and subtract it by '0' (not shown in code, mb) to convert it to int it says it's a "std::basic_string-char-" so it cant do the subtraction with type char.
postfix.cpp:
#include <iostream>
#include <string>
#include "ArrayStack.h"
bool IsNumericDigit(char C)
{
if(C >= '0' && C <= '9') return true;
return false;
}
// Function to verify whether a character is operator symbol or not.
bool IsOperator(char C)
{
if(C == '+' || C == '-' || C == '*' || C == '/')
return true;
return false;
}
// Function to perform an operation and return output.
int PerformOperation(char operation, int operand1, int operand2)
{
if(operation == '+') return operand1 +operand2;
else if(operation == '-') return operand1 - operand2;
else if(operation == '*') return operand1 * operand2;
else if(operation == '/') return operand1 / operand2;
else std::cout<<"Unexpected Error \n";
return -1;
}
int EvaluatePostfix(std::string expression, StackInterface<std::string>* stackPtr)
{
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 the result back.
else if(IsOperator(expression[i]))
{
// Pop two operands.
int operand2 = stackPtr->peek();
stackPtr->pop();
int operand1 = stackPtr->peek();
stackPtr->pop();
//operand1 and operand2 are reversed in case of Prefix Expression
// Perform operation
int result = PerformOperation(expression[i], operand1, operand2);
//Push back result of operation on stack.
stackPtr->push(result);
}
else if(IsNumericDigit(expression[i]))
{
// Extract the numeric operand from the string
// Keep incrementing i as long as you are getting a numeric digit.
int operand = 0;
while(i<expression.length() && IsNumericDigit(expression[i]))
{
// For a number with more than one digits, as we are scanning from left to right.
// Everytime , we get a digit towards right, we can multiply current total in operand by 10
// and add the new digit.
operand = (operand*10) + (expression[i] - '0');
std::cout << operand << std::endl;
i++;
}
// Finally, you will come out of while loop with i set to a non-numeric character or end of string
// decrement i because it will be incremented in increment section of loop once again.
// We do not want to skip the non-numeric character by incrementing i twice.
i--;
// Push operand on stack.
stackPtr->push(operand);
}
}
// If expression is in correct format, Stack will finally have one element. This will be the output.
return stackPtr->top();
}
int main(){
StackInterface<std::string>* stackPtr = new ArrayStack<std::string>();
std::string expression;
std::cout<<"Enter Postfix Expression \n";
std::getline(std::cin,expression);
EvaluatePostfix(expression, stackPtr)
std::cout << stackPtr->push(expression);
}
ArrayStack.h:
#ifndef ARRAY_STACK_EXCEPTIONS
#define ARRAY_STACK_EXCEPTIONS
#include "StackInterface.h"
#include "PrecondViolatedExcep.h"
const int MAX_STACK = 1000;
template<class ItemType>
class ArrayStack : public StackInterface<ItemType>
{
private:
ItemType items[MAX_STACK]; // Array of stack items
int top; // Index to top of stack
public:
ArrayStack();
bool isEmpty() const;
bool push(const ItemType& newEntry);
bool pop();
ItemType peek() const;
}; // end ArrayStack
template<class ItemType>
ArrayStack<ItemType>::ArrayStack() : top(-1)
{
} // end default constructor
// Copy constructor and destructor are supplied by the compiler
template<class ItemType>
bool ArrayStack<ItemType>::isEmpty() const
{
return top < 0;
} // end isEmpty
template<class ItemType>
bool ArrayStack<ItemType>::push(const ItemType& newEntry)
{
bool result = false;
if (top < MAX_STACK - 1)
{
// Stack has room for another item
top++;
items[top] = newEntry;
result = true;
} // end if
return result;
} // end push
template<class ItemType>
bool ArrayStack<ItemType>::pop()
{
bool result = false;
if (!isEmpty())
{
result = true;
top--;
} // end if
return result;
} // end pop
template<class ItemType>
ItemType ArrayStack<ItemType>::peek() const
{
// Enforce precondition
if (isEmpty())
throw PrecondViolatedExcep("peek() called with empty stack");
// Stack is not empty; return top
return items[top];
} // end peek
Edit: The error I get when subtracting stackPtr->peek() by '0' is "no match for 'operator-' (operand types are 'std::basic_stringchar' and
char'"
Thanks!
The problem here is that you are using std::string, char, and int interchangeably, while they are not.
Notice that your data type for you stack is string, and there isn't default way to change from string to int or string to char.
Based on your descriptions, you were trying to get the first char out of the string, which you would probably call either:
c = stackPtr->peek()[0];
or
c = stackPtr->peek().front();
string to int would call std::stoi(stackPtr->peek()), but not sure if you want it as you are implementing it yourself.
So you probably want to extract this part as a separate function:
while(i<expression.length() && IsNumericDigit(expression[i]))
{
operand = (operand*10) + (expression[i] - '0');
std::cout << operand << std::endl;
i++;
}
so you can easily reuse it when you get a string from your stack.
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;
}
#include<iostream>
#include<cstring>
#include<string>
#include "linkedStack.h"
#include <fstream>
#include <iomanip>
#include "ArgumentManager.h"
using namespace std;
int getPrecedence(char ch) //this function will decide and return precedence for the operators and operand
{
switch (ch)
{
case '/':return 2;
break;
case '*': return 2;
break;
case '+': return 1;
break;
case '-': return 1;
break;
default: return 0;
}
}
string infixToPostfix(const string& expression) // this function will convert the infix expression to postfix by passing the infix expression string
{
int size = expression.size(); //size of infix string
char infix[expression.size()]; //converting string into array of chars
strncpy(infix, expression.c_str(), sizeof(infix));
infix[sizeof(infix)] = '\0'; //adding 0 for array ending
char postfix[strlen(infix)]; // create a char array with the size of the infix string length
linkedStack s;
int precedence;
int i = 0;
int k = 0;
char ch;
//iterate the infix expression
while (i < size)
{
ch = infix[i];
//push opening parenthesis to stack
if (ch == '(')
{
s.push(ch);
i++;
continue;
}
if (ch == ')')
{
while (!s.empty() && s.top() != '(') // if closing parenthesis is found pop of all the elements and append it to the postfix expression till we encounter an opening parenthesis
{
postfix[k++] = s.top();
s.pop();
}
if (!s.empty())
{
s.pop(); // pop the opening parenthesis
}
i++;
continue;
}
precedence = getPrecedence(ch);
if (precedence == 0)
{
postfix[k++] = ch; // if an operand is found add it to the postfix expression
}
else
{
if (s.empty())
{
s.push(ch); //push operator onto stack if the stack is empty
}
else
{
while (!s.empty() && s.top() != '(' && precedence <= getPrecedence(s.top())) // pop of all the operators from the stack to the postfix expression till we see an operator with a lower precedence than the current operator
{
postfix[k++] = s.top();
s.pop();
}
s.push(ch); // push the current operator to stack
}
}
i++;
}
while (!s.empty()) // pop all of the the remaining operators in the stack and add it to postfix
{
postfix[k++] = s.top();
s.pop();
}
postfix[k] = '\0'; // add null character to end of character array for c string
string postfixStr = postfix; //covert the final postfix char array to a string
return postfixStr; // returns the final postfix expression as a string
}
int main(int argc, char* argv[])
{
ArgumentManager am(argc, argv);
string infilename = am.get("A");
string outfilename = am.get("C");
string expression1;
ifstream infile;
infile.open(infilename);
if (infile.good())
{
getline(infile, expression1); //gets the infix string from file
}
infile.close(); //close the infile stream
string expression2 = "12 + 3 / 4";
string postfix1 = infixToPostfix(expression1);
string postfix2 = infixToPostfix(expression2);
cout << expression1 << endl;
cout << postfix1 << endl;
cout << expression2 << endl;
cout << postfix2 << endl;
return 0;
}
Hi, I'm having trouble with my output with my infix to post fix converter using stack. For instance in the case of "12 + 3 / 4" the output should be "12 3 4 / +" with the characters evenly spaced by one white space. However, it is adding unnecessary white spaces or none at all. For the test case above you can see the problem I'm running into in the attached pic or below. The first line is the infix the second is the post fix output. There are two cases here.Output Example
25 + ( 4 * 5 ) - 12
25 4 5 * + 12-
12 + 3 / 4
12 3 4/+
1) This code :
int size = expression.size(); //size of infix string
char infix[expression.size()]; //converting string into array of chars
strncpy(infix, expression.c_str(), sizeof(infix));
infix[sizeof(infix)] = '\0'; //adding 0 for array ending
could be replaced by :
char * infix = new char [expression.length()+1];
std::strcpy (infix, expression.c_str());
2) This code pop values without repush them into s after.
while (!s.empty() && s.top() != '(' && precedence <= getPrecedence(s.top())) // pop of all the operators from the stack to the postfix expression till we see an operator with a lower precedence than the current operator
{
postfix[k++] = s.top();
s.pop();
}
Thanks for all the advice. In the end I did a few things to achieve the desired output. First, I increased the postfix array. Next, in two certain spots in the loop, whenever it appended to the postfix array I would also add a space.
Here:
while (!s.empty() && s.top() != '(' && precedence <= getPrecedence(s.top())) // pop of all the operators from the stack to the postfix expression till we see an operator with a lower precedence than the current operator
{
postfix[k++] = s.top();
postfix[k++] = ' ';
s.pop();
}
And here:
while (!s.empty()) // pop all of the the remaining operators in the stack and add it to postfix
{
postfix[k++] = s.top();
postfix[k++] = ' ';
s.pop();
}
Lastly, I used a separate function to trim any extra spaces in the final string.
A little messy but gets the job done.
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.
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 :(.