I put the following code together to transform infix to postfix. However it only works when the infix is parenthesised, and I have no clue why. I tried a lot of the basic stuff like directly/indirectly assigning the values.
Here's the code
int prec(char c)
{
if(c == '^')
return 3;
else if(c == '*' || c == '/')
return 2;
else if(c == '+' || c == '-')
return 1;
else
return -1;
}
class Expressions
{
public:
std::stack <char> inFix;
std::stack <char> postFix;
std::vector <char> postFixString;
void ptInFix(); // prints the infix and deletes the stack, for testing only, need to tweak later
void ptPostFix();
void inFixtoPostFix();
};
void Expressions::inFixtoPostFix()
{
int size = inFix.size();
for(int i=0;i<size;i++)
{
if((inFix.top() >= 'a' && inFix.top() <= 'z')||(inFix.top() >= 'A' && inFix.top() <= 'Z'))
{
postFixString.push_back(inFix.top());
inFix.pop();
}
else if(inFix.top() == '(')
{
postFix.push(inFix.top());
inFix.pop();
}
else if(inFix.top() == ')')
{
while(postFix.top() != '(')
{
postFixString.push_back(postFix.top());
postFix.pop();
}
if(postFix.top()=='(')
{
postFix.pop();
}
inFix.pop();
}
else if(inFix.top() == '^' || inFix.top() == '*' || inFix.top() == '/' || inFix.top() == '+' || inFix.top() == '-')
{
if(postFix.empty())
{
postFix.push(inFix.top());
inFix.pop();
}
else if(postFix.empty()!=1)
{
while((prec(postFix.top())>=prec(inFix.top())))
{
char c = postFix.top();
postFix.pop();
postFixString.push_back(c);
}
postFix.push(inFix.top());
inFix.pop();
}
}
}
int s = postFix.size();
for(int i=0;i<s;i++)
{
postFixString.push_back(postFix.top());
postFix.pop();
}
}
And this works
Expressions test;
char infix[] = ("(A+B)*(C+D)");
for(int i=(sizeof(infix)-1);i>=0;i--)
{
test.inFix.push(infix[i]);
}
test.inFixtoPostFix();
std::cout<<"\n";
for(int i=0; i<test.postFixString.size(); i++)
{
printf("%c ",test.postFixString[i]);
}
std::cout<<"\n";
But this doesn't, does not output anything at all
Expressions test2;
char infix2[] = ("A+B*C+D");
for(int i=(sizeof(infix2)-1);i>=0;i--)
{
test2.inFix.push(infix2[i]);
}
test2.inFixtoPostFix();
std::cout<<"\n";
int s = test2.postFixString.size();
for(int i=0; i<s; i++)
{
std::cout<<(test2.postFixString[i]) ;
}
std::cout<<"\n";
Since every time I ran the second test case the command window studderes so I suspect there's some kind of memory issue but have not idea where. I had a lot of outputs in the actual function to debug but didn't help so I deleted those for clearity.
Related
My problem is that my evaluatePostfix() function is not calculating operands. It only returns the top of the stack in the converted postfix expression.
So for example, my output is:
Enter a infix expression: 1+4
your postfix expression is:
14+
your result is:
4
Why am I not getting 5?
Here's my main():
int main()
{
string infixExp = "";
cout << "Enter a infix expression: ";
cin >> infixExp;
cout << "your postfix expression is: " << endl;
infixToPostfix(infixExp);
cout << endl;
cout << "your result is: " << endl;
cout << evaluatePostfix(infixExp) << endl;
}
Here's evaluatePostfix():
int evaluatePostfix(string expression)
{
ArrayStack<int> S;
for (int i = 0; i < expression.length(); i++)
{
if (expression[i] == ' ' || expression[i] == ',') continue;
else if(IsOperator(expression[i]))
{
int operand2 = S.peek();
S.pop();
int operand1 = S.peek();
S.pop();
int result = PerformOperation(expression[i], operand1, operand2);
S.push(result);
}
else if(IsNumericDigit(expression[i]))
{
int operand = 0;
while (i < expression.length() && IsNumericDigit(expression[i]))
{
operand = operand * 10 + expression[i] - '0';
i++;
}
i--;
S.push(operand);
}
}
return S.peek();
}
Here's PerformOperation(), IsOperator(), IsNumericDigit(). These are all in evaluatePostfix.
bool IsNumericDigit(char C)
{
if (C >= '0' && C <= '9')
{
return true;
}
else
{
return false;
}
}
bool IsOperator(char C)
{
if (C == '+' || C == '-' || C == '*' || C == '/')
{
return true;
}
else
{
return false;
}
}
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
{
cout << "error" << endl;
}
return -1;
}
Lastly, here is infixToPostfix():
void infixToPostfix(string s)
{
ArrayStack<char> stackPtr;
string postfixExp;
for (int i = 0; i < s.length(); i++)
{
char ch = s[i];
if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || (ch >= '0' && ch <= '9'))
{
postfixExp += ch;
}
else if (ch == '(')
{
stackPtr.push('(');
}
else if (ch == ')')
{
while(stackPtr.peek() != '(')
{
postfixExp += stackPtr.peek();
stackPtr.pop();
}
stackPtr.pop();
}
else
{
while (!stackPtr.isEmpty() && prec(s[i]) <= prec(stackPtr.peek()))
{
postfixExp += stackPtr.peek();
stackPtr.pop();
}
stackPtr.push(ch);
}
}
while (!stackPtr.isEmpty())
{
postfixExp += stackPtr.peek();
stackPtr.pop();
}
cout << postfixExp << endl;
}
I'd like to create a function that checks whether a number input with an exponent such as 1.32e2, 1e3, +1.32e+2 indeed has the e in the correct position, after a number, not before it (such as e1 or .e4)
I'm a beginner so it's just trial and error at this point. This is what I have so far:
bool validate_alpha_e(string op) {
if (count_alpha(op) <= 1) {
if (count_es(op) == 1) {
//return true;
int length = op.length();
for (int i = 0; i < length; i++) {
char ch = op[i-1];
if (ch == 'e' || ch == 'E') {
if (i-1 != isdigit(i)) {
return false;
}
}
}
return true;
}
Worked it out. Thanks for the comments but I wasn't able to figure it out.
So I had to create 3 separate functions (see below)
First function validates for correct input before the e.
Second function validates for correct input after the e.
Third function validates that the first character is not an e.
Put all these together in a bool if statement and if it returns false then the input is not correct.
bool validate_e_after(string op) {
int length = op.length();
for (int i = 1; i < length; i++) {
char ch = op[i-1];
if (ch == 'e' || ch == 'E') {
char ch2 = op[i];
if (isdigit(ch2) || ch2 == '+' || ch2 == '-') {
return true;
}
else {
return false;
}
}
}
}
bool validate_e_before(string op) {
int length = op.length();
for (int i = 1; i < length; i++) {
char ch = op[i+1];
if (ch == 'e' || ch == 'E' && i != 0) {
char ch2 = op[i];
if (isdigit(ch2) || ch2 == '+' || ch2 == '-') {
return true;
}
else {
return false;
}
}
}
}
bool validate_ezero(string op) {
int length = op.length();
for (int i = 0; i < length; i++) {
char ch = op[i];
if (ch == 'e' or ch == 'E') {
if (i == 0) {
return false;
}
}
}
return true;
Below is an simple program to convert infix expression to postfix expression. It takes an infix expression in main program and after passing values in function converter, it returns a postfix expression as string.
#include<iostream>
#include<stdio.h>
#include<string>
#include <stack>
using namespace std;
int priority(char o) {
if (o == '(' || o == ')')
return -1;
else if (o == '*' || o == '/')
return 2;
else if (o == '+' || o == '-')
return 1;
else if (o == '^' )
return 3;
}
string converter(stack <char>s, string in) {
string pf;
int i;
for (i = 0; i < in.length(); i++) {
if ((in[i] >= 'a' && in[i] <= 'z') || (in[i] >= 'A' && in[i] <= 'Z') ){
pf+= in[i];
}
else if (in[i] == '(') {
s.push(in[i]);
}
else if (in[i] == ')') {
while (s.top() != '(' && (!s.empty())) {
char temp = s.top();
pf += temp;
s.pop();
}
}
else {
if (s.empty()) {
s.push(in[i]);
}
else {
if (priority(in[i]) > s.top()) {
s.push(in[i]);
}
else if (priority(in[i]) == s.top()&&(in[i]=='^')) {
s.push(in[i]);
}
else {
while (priority(in[i]) <= s.top()&&(!s.empty())) {
char temp = s.top();
pf += temp;
s.pop();
}
s.push(in[i]);
}
}
}
}
while (!s.empty()) {
char temp = s.top();
pf += temp;
s.pop();
}
return pf;
}
int main() {
string infix,postfix;
cout << "input an infix expression"<<endl;
cin >> infix;
stack <char> s;
postfix = converter(s, infix);
cout << "Postfix expression is:" << postfix;
return 0;
}
Every time I try to run the program, it gives runtime error.
It works till taking an infix expression but the function aborts abnormally.
I can't find the bug. I use visual studios. Is it a problem in my visual studios or a logic error, really don't know.
This bit:
while (priority(in[i]) <= s.top()&&(!s.empty()))
Accessing a stack's top when it's empty invokes undefined behavior, and that's exactly what's happening here, as priority(in[i]) <= s.top() will be checked first.
You should move the !s.empty() condition first. If it evaluates to true then the second condition will not be checked. This is called Short-circuit evaluation.
while (!s.empty() && priority(in[i]) <= s.top())
I'm a C++ newcomer.
For the next project in class, the professor asked us to code a program that calculates a mathematical expression, that we input an infix notation, convert it to postfix and calculates it. I think I have pretty much finished the code, but there are some lines that I'm probably doing wrong and I don't really know what is it. Can you please take a look at it and tell me why am I wrong.
#include <iostream>;
#include <stack>;
#include <string>;
using namespace std;
bool operatorCheck(char c)
{
if (c == '+' || c == '-' || c == '*' || c == '/')
{
return true;
}
return false;
}
int priority(char c)
{
if (c == '*' || c == '/')
{
return 2;
}
else if (c == '+' || c == '-')
{
return 1;
}
return 0;
}
string InfixToPostfix(string expression)
{
stack<char> operators;
string postfix;
for (int i = 0;i< expression.length();i++)
{
if (expression[i] == ' ')
{
continue;
}
else if (expression[i] >= '0' && expression[i] <= '9')
{
string temp;
temp += expression[i];
int temp2 = i + 1;
while (true)
{
if (expression[temp2] >= '0' && expression[temp2] <= '9')
{
temp += expression[temp2];
temp2 += 1;
}
else
{
break;
}
}
postfix= postfix + temp + " ";
}
else if (operators.empty())
{
operators.push(expression[i]);
}
else if (operatorCheck(expression[i]))
{
if (priority(operators.top()) < priority(expression[i]))
{
operators.push(expression[i]);
}
else
{
while (!operators.empty() && priority(operators.top()) < priority(expression[i]))
{
postfix += operators.top();
operators.pop();
}
operators.push(expression[i]);
}
}
else if (expression[i] == '(')
{
operators.push(expression[i]);
}
else if (expression[i] == ')')
{
while (!operators.empty() && operators.top() != '(')
{
postfix += operators.top();
operators.pop();
}
operators.pop();
}
}
while (!operators.empty())
{
postfix += operators.top();
operators.pop();
}
return postfix;
}
//Main program
int main()
{
string expression;
stack<int> calc;
cout << "Welcome to my program!" << endl;
cout << "This program will help you to calculate arithmetic expression." << endl;
cout << "Please enter an arithmetic expression (Remember to enter space between numbers and operators):" << endl;
getline(cin, expression);
string postfix = InfixToPostfix(expression);
cout << postfix << endl;
for (int i = 0;i < postfix.length();i++)
{
if (postfix[i] == ' ')
{
continue;
}
else if (postfix[i] >= '0' && postfix[i] <= '9')
{
string temp;
int temp2 = i + 1;
temp += postfix[i];
while (true)
{
if (postfix[temp2] >= '0' && postfix[temp2] <= '9')
{
temp += expression[temp2];
temp2 += 1;
}
else
{
break;
}
}
int n = atoi(temp.c_str());
calc.push(n);
}
else if (postfix[i] == '+')
{
int temp1 = calc.top();
calc.pop();
int temp2 = calc.top();
calc.pop();
int result = temp2 + temp1;
calc.push(result);
}
else if (postfix[i] == '-')
{
int temp1 = calc.top();
calc.pop();
int temp2 = calc.top();
calc.pop();
int result = temp2 - temp1;
calc.push(result);
}
else if (postfix[i] == '*')
{
int temp1 = calc.top();
calc.pop();
int temp2 = calc.top();
calc.pop();
int result = temp2 * temp1;
calc.push(result);
}
else if (postfix[i] == '/')
{
int temp1 = calc.top();
calc.pop();
int temp2 = calc.top();
calc.pop();
int result = temp2 / temp1;
calc.push(result);
}
}
cout << calc.top() << endl;
}
For example, with this expression ( ( 7 + 6 ) * ( 16 - 2 ) ) / 2,
It returns 7 6 +16 6 2 -*2 / ( there is an extra 6) for the postfix. Why is this happened?
I'm Writing a program to implement postfix calculator, its giving me completely wrong answers.
Really appreciate the help
class stacks {
public:
typedef int List;
static const int size = 100;
stacks() {
use = 0;
}
void push(List entry) {
data[use] = entry;
++use;
}
List pop() {
if(!empty()) {
--use;
return data[use];
}
}
bool empty() const {
return use == 0;
}
int Size() const {
return use;
}
private:
List data[size];
int use;
};
int main() {
stacks s;
string input;
int final;
ifstream infile("foo.txt",ios::in);
while (getline(infile, input))
cout << "Expression: ";
for (int i = 0; i<input.length(); i++) {
cout << input[i];
auto oper1 = s.pop();
auto oper2 = s.pop();
if(input[i] == '1' || input[i] == '2' || input[i] == '3' || input[i] == '4' || nput[i] == '5' || input[i] == '6' || input[i] == '7' || input[i] == '8' || input[i] == '9')
s.push(input[i] - '0');
if(input[i] == '+')
s.push(oper1 + oper2);
if(input[i] == '-')
s.push(oper1 - oper2);
if(input[i] == '*')
s.push(oper1 * oper2);
if(input[i] == '/')
s.push(oper1 / oper2);
}
final = s.pop();
cout << endl << "Value = " << final << "." << endl << endl;
}
What do you recommend?
Thanks
You need to wait to pop() until you know you have an operator. You're popping stuff off the stack when you shouldn't be.