infix to postfix expressrion not showing any output - c++

infix to posfix expresion where a+b is converted in ab+.
i have been staring at the code for hours and wondering why is not showing any output at all. i tried reviewing it by line to the best that i could and still could not figure it out why. can anyone point out where im wrong or is it my code does not make any sense at all. also, i am only allowed to use array and string.
#include<iostream>
using namespace std;
string stack; //initialize stack to contain operators
int top=-1;
void push(char a){ //add/push it to stack
top++;
stack[top] = a;
}
char pop(){ //delete/pop the stack
return stack[top--];
}
int order_operation(char a){ //the precedence priority
if(a=='+' || a=='-'){
return 1;
}
else if(a=='*' || a=='/'){
return 2;
}
else {
return 3;
}
}
int main(){
string infix,postfix;
cout<<"infix: ";
getline(cin,infix);
for(int x = 0; x<infix.length(); x++){ //scan the infix for operator
if(infix[x]=='-' || infix[x]=='+' ||infix[x]=='*' || infix[x]=='/'){
while(!stack.empty() && order_operation(stack[top])>=order_operation(infix[x])){ //if the stack is not empty and check the precedence
postfix+=stack[top]; //add it to postfix string
pop(); //pop the stack operator
}
push(infix[x]);
}
else{
postfix+=infix[x]; //add to postfix string if its operand
}
}
while(!stack.empty()){ //if the stack is not empty put it to posfix string
postfix+=stack[top];
pop();
}
cout<<postfix;
}

You need to add endl as stated by #Carcigenicate.
Your pop() method is incorrect. It should pop and return the actual value at the top of the stack, and it should not take an argument. At present you are corrupting the stack every time you pop it.

Related

Issues with a char stack implementation in c++?

I want to make a char stack implementation, but i think something is wrong with it because when i try to use it for my other function it does not word and library stack works. Can you help to find an issue:
using namespace std;
Stack::Stack(int size)
{
arr = new char[size];
capacity = size;
t = -1;
}
int Stack::size()
{
return (t + 1);
}
Stack::~Stack()
{
delete[] arr;
}
bool Stack::empty()
{
return size()==0;
}
void Stack::push(char x)
{
if (size()==capacity) {
cout<<"Push to full stack";
arr[++t]=x;
}
}
char Stack::pop()
{
if (empty()) {
cout<<"Pop from empty stack";
--t;
}
return 0;
}
char Stack::top()
{
if (!empty())
return arr[t];
else
cout<<"Top of the stack is empty";
return 0;
}
I want to make a char stack implementation, but i think something is wrong with it because when i try to use it for my other function it does not word and library stack works. Can you help to find an issue:
Thank you in advance!
I think you need to make some changes to the push and pop function for your Stack to work
In push, you should put arr[++t]=x; outside the if statement instead of inside as you want to add value to arr if the current size is less than its capacity instead of when it is equal
In pop, you should put arr[--t]; outside the if statement instead of inside as you want to remove and return the last value in the array if the stack is not empty. When it is empty, you should consider returning a default character such as the null terminator character \0. You should also want to use arr[t--] instead of arr[--t] as the last element is currently at t so you want it to evaluate arr[t] before decreasing its value (t--)
void Stack::push(char x)
{
if (size()==capacity) {
cout<<"Push to full stack";
return;
}
arr[++t]=x;
}
char Stack::pop()
{
if (empty()) {
cout<<"Pop from empty stack";
return '\0';
}
return arr[t--];
}

Infix to Postfix Using Stacks C++: Error Code 6

My assignment is to implement stacks using singly linked lists to convert a string which is in infix form to postfix form. For simplicity, this string does not contain any spaces.
My algorithm in a nutshell is:
read character from infix string
create a temp node with the character and its associated precedence in the order of operations
push it onto the stack if it is an operation and not a number/if it is a number, automatically append it to the postfix string
every time a character is pushed onto the stack, if the top node of the stack has a higher precedence than the temp node of the next character, pop it from the stack and append it to the postfix string.
These steps work when doing an infix to postfix by hand.
Whenever I try to run my code, I keep getting an error 6 SIGABRT. My code should be easy to understand. Can anyone tell me what this error means, why I am getting it, and how to fix it so that my code outputs the postfix string properly?
#include <iostream>
#include <string>
using namespace std;
string postfix; //infix and postfix strings
//function to return true if a character is an operation
bool isoperator(char a)
{
if(a == '(' || ')' || '*' || '/' || '+' || '-') //might need to
change to "" instead of ''
{
return(true);
}
else
{
return(false);
}
}
//node class
class node
{
public:
char character;
//double number;
int level; //to check for precedence of operations
node *ptr;
void assignlevel()
{
switch(character)
{
case ')':
level = 3;
break;
case '(':
level = 0;
break;
case '+':
level = 1;
break;
case '-':
level = 1;
break;
case '*':
level = 2;
break;
case '/':
level = 2;
break;
default:
level = 0;
}
}
friend class stack;
};
//stack class
class stack
{
public:
node *top, *temp;
//Constructor Function
stack()
{
top = new node;
top->character = '&';
top->ptr = NULL;
top->level = 0;
temp = new node;
temp->ptr = NULL;
}
//Empty
bool empty()
{
return(top->character == '&');
}
//Read character from string
void readchar(char a)
{
temp->character = a;
temp->assignlevel();
}
//Check Precedence of top and temp
bool precedence()
{
return(top->level >= temp->level);
}
//Push function for infix to postfix
void push1(char a)
{
readchar(a);
if(isoperator(temp->character)) //Push onto stack if character is an operation
{
if(empty())
{
top->character = temp->character;
top->assignlevel();
}
else
{
node *v = new node;
v->character = temp->character;
v->level = temp->level;
v->ptr = top;
top = v;
delete v;
}
}
else //append to string if character is number
{
postfix += temp->character;
}
if(precedence()) //we check if we have to pop every time we push
onto the stack
{
pop1();
}
}
void pop1() //Pop onto postfix string
{
postfix += top->character;
node *w = top->ptr;
delete &top;
top = w;
delete w;
}
};
int main()
{
string infix = "2+3-5*(7+1)";
stack op;
for(int i = 0; i < infix.size(); ++i)
{
op.push1(infix[i]);
}
for(int j = 0; j < infix.size(); j++)
{
cout << postfix[j];
}
return 0;
}
Why do you do "delete v" in push? This deletes the node you have just created.

infix to postfix program

I have written the following infix to postfix program but it's not working.
My program takes input but doesn't show any result. Can anyone help find the problem in my program.
And also it would be a great help if you tell if my Algorithm for converting infix to postfix is correct or not.
using namespace std;
class Stack
{
private:
int top;
char s[mx];
public:
Stack()
{
top=-1;
}
void push(char c)
{
if(!stackFull())
s[++top]=c;
}
void pop()
{
if(!stackEmpty())
top--;
else cout<<"Stack is empty"<<endl;
}
char topShow()
{
if(!stackEmpty())
return s[top];
}
bool stackEmpty()
{
if(top==-1)
return 1;
else return 0;
}
bool stackFull()
{
if(top == (mx-1))
return 1;
else return 0;
}
};
class Expression
{
private:
char entry2;
int precedence;
char infix[mx];
char postfix[mx];
public:
int prec(char symbol)
{
switch(symbol)
{
case '(':return 0; break;
case '-':return 1; break;
case '+':return 2; break;
case '*':return 3; break;
case '/':return 4; break;
}
}
void Read()
{
cout<<"Enter the infix expression: ";cin>>infix;
for(int i=0;infix[i]!='\0';i++)
{
convertToPostfix(infix[i]);
}
}
void ShowResult()
{
cout<<"Postfix expression"<<endl;
for(int j=0;postfix[j]!='\0';j++)
{
cout<<postfix[j];
}
}
void convertToPostfix(char c)
{
int p=0;
Stack myStack;
precedence=prec(c);
entry2=myStack.topShow();
if(isdigit(c))
{
postfix[++p]=c;
}
if(precedence>prec(entry2))
{
myStack.push(c);
}
if(precedence<prec(entry2))
{
switch(c)
{
case '(': myStack.push(c); break;
case ')': while(myStack.topShow()!= '(')
{
postfix[++p]=myStack.topShow();
myStack.pop();
};myStack.pop();break;
case '+':
case '-':
case '*':
case '/': while(prec(myStack.topShow())>=precedence)
{
postfix[++p]=myStack.topShow();
myStack.pop();
};break;
}
}
}
};
int main()
{
Expression myExp;
myExp.Read();
myExp.ShowResult();
return 0;
}
Here are some issues I found:
Boolean Functions Return true or false
Match return types with return values. The numbers 1 and 0 are not Boolean values.
Precedence table
Add and subtract have same precedence.
Multiply and divide have same precedence.
Multiply and divide have higher precedence than add and subtract.
Stack disappears
Since the stack is declared as a local variable in the function, it will be created fresh when entering the function and destroyed before exiting the function.
Solution: move it to the class as a class member or declare it as static.
Multiple statements per line are not more efficient
Blank lines and newlines do not affect performance, and add negligible time to the build.
However, they make your program more readable which helps when inspecting or debugging. Use them.
And similarly with space before and after operators.
Build the habit now rather than correcting when you get a job.
Call function once and store the value
You call prec(entry2) twice, which is a waste of time. Call it once and save the value in a variable. Similarly with stack.TopShow().
Use std::vector not an array
The std::vector will grow as necessary and reduce the chance of buffer overflow.
With an array, you must check that your indices are always within range. Also, array capacities don't change; you have to declare a new instance and copy the data over.
The variable mx is not declared
The compiler should catch this one. You use mx as the capacity for an array and comparing for full. However, it is never declared, defined nor initialized. Prefer std::vector and you won't have to deal with these issues.
Input is not validated
You input a letter, but don't validate it.
Try these characters: space, #, #, A, B, etc.
Missing default for switch
Crank up your compiler warnings to maximum.
Your switch statements need defaults.
What precedence do numeric characters ('0'..'9') have?
(You check the precedence of numeric characters.)
Check all paths through your functions and program.
Using a debugger (see below) or pen and paper, check your program flow through you functions. Include boundary values and values not within the bounds.
Case statements: break or return
You don't need a break after a return statement. Think about it. Can the program continue executing at the line after a return statement?
Use a debugger or print statements
You can print variables at different points in your program. This is an ancient technique when debuggers are not available.
Learn to use a debugger. Most IDEs come with them. You can single step each statement and print out variable values. Very, very, useful.
class infixToPostfix{
public static void postfix(String str){
Stack<Character> stk = new Stack<Character>();
for(Character c : str.toCharArray()){
// If operands appears just print it
if(c >= 'A' && c <= 'Z' || c >= 'a' && c <= 'z'){
System.out.print(c);
}else{
// Open paranthesis push is
if(c == '('){
stk.push(c);
//Close paranthesis pop until close paranthesis
}else if( c == ')'){
while(stk.peek() != '(')
System.out.print(stk.pop());
stk.pop();
// check the precedence of operator with the top of stack
}else if(c == '+' || c == '-'){
if(!stk.isEmpty()){
char top = stk.peek();
if(top == '*' || top == '/' || top == '+' || top == '-'){
System.out.print(stk.pop());
}
}
stk.push(c);
}else{
if(!stk.isEmpty()){
char top = stk.peek();
if(top == '/' || top == '*'){
System.out.print(stk.pop());
}
}
stk.push(c);
}
}
}
//Print all the remaining operands
while(!stk.isEmpty()) System.out.print(stk.pop());
System.out.println();
}
public static void main(String args[]){
String str = "A+B-(c+d*Z+t)/e";
postfix(str);
}
}
using stack and map u can solve the problem
1) create a map having operator as key and some integer to set priority. operator with same precedence will have same value something like:
map<char,int>oprMap;
oprMap['^'] = 3;
oprMap['*'] = 2;
oprMap['/'] = 2;
oprMap['+'] = 1;
oprMap['-'] = 1;
2) iterate through given expression call these checks
1) if current element
i) is operand add it to result
ii) not operand do following check
a. while not (stack is empty and element is open bracket and found operator with higher precedence.
add top of the stack to the result and pop()
b. push current element to stack
iii) if open brackets push to stack
iv) if closed brackets pop until get closed bracket and add it to result
3) while stack is not empty pop() and add top element to the result.
{
stack<char>S;
for (int i = 0; i < n; i++) {
if(isOperand(exps[i])) {
res = res + exps[i];
} else if(isOperator(exps[i])){
while(!(S.empty() && isOpenParanthesis(S.top()) && isHeigherPrecedence(S.top(),exps[i])){
res = res+S.top();
S.pop();
}
S.push(exps[i]);
} else if(isOpenParanthesis(exps[i])) {
S.push(exps[i]);
} else if(isClosingParanthesis(exps[i])) {
while(!S.empty() && !isOpenParanthesis(S.top())) {
res = res+S.top();
S.pop();
}
S.pop();
}
}
while(!S.empty()) {
res = res + S.top();
S.pop();
}
}
}
#include<bits/stdc++.h>
using namespace std;
// This isHigher function checks the priority of character a over b.
bool isHigher(char a,char b)
{
if(a=='+' || a=='-')
return false;
else if((a=='*' && b=='*') || (a=='*' && b=='/') || (a=='/' && b=='*') ||
(a=='/' && b == '/')|| (a=='^' && b=='^')||(a=='*' && b=='^') || (a=='/' &&
b=='^'))
return false;
return true;
}
int main(){
string s;
cin>>s;
s = s + ")";
//Vector postfix contains the postfix expression.
vector<char>postfix;
stack<char>mid;
mid.push('(');
for(int i=0;i<s.length();i++)
{
if(s[i] == '(')
mid.push(s[i]);
else if(s[i] == '+' || s[i] == '^' || s[i] == '-' || s[i] == '*'||
s[i] == '/')
{
if(mid.top() == '(')
mid.push(s[i]);
else {
if(isHigher(s[i],mid.top()))
mid.push(s[i]);
else
{
while(mid.top()!='(')
{
if(!isHigher(s[i],mid.top()))
{
postfix.push_back(mid.top());
mid.pop();
}
else
break;
}
mid.push(s[i]);
}
}
}
else if(s[i] == ')')
{
while(mid.top() != '(')
{
postfix.push_back(mid.top());
mid.pop();
}
mid.pop();
}
else
postfix.push_back(s[i]);
}
for(int i=0;i<postfix.size();i++)
cout<<postfix[i];
return 0;
}

Evaluating postfix expression. pop() returns incorrect values to calculate function

I am writing a program that converts infix to postfix (through a stack implememnted by linked list), stored in a character array and evaluate the postfix expression. Works fine till conversion.
But when I call the function to evaluate the postfix expression, it gives incorrect answers.
The problem starts at the point where function, evalPfExpression() of class expEvaluator pops a number from the character array of postfix. (highlighted through capital comments in code.)
First it gave completely wrong numbers. But subtracting 48 from each number fixed it for single digits.(noticed every single digit was given with 48 added). But it still gives wrong answers for 2 digit or higher numbers.
I guess it might have something to do with converting between "char" and "int" types.
Would appreciate the help.
#include <iostream>
#include <conio.h>
using namespace std;
////The node of the stack:
class node
{
public:
char value;
node* next;
};
////The basic stack class:
class stack
{
public:
int size;
node* top;
stack() //default constructor for stack
{
size=0;
top=NULL;
}
void push(char);
char pop();
char topstack();
void print();
bool isEmpty();
};
//Stack's push function:
void stack::push(char e)
{
node *temp;
temp =new node;
temp->next = top;
temp->value=e;
top=temp;
size++;
}
//Stack's pop function:
char stack::pop()
{
char d;
if (isEmpty())
{
cout<<"\nStack is Empty\n";
return '!';
}
else
{
node *temp = top;
top=top->next;
d=temp->value;
delete temp;
size--;
}
return d;
}
//Returns a copy of the stack's top element.
char stack::topstack()
{
if(size==0)
return '\0';
else
return top->value;
}
//To print the stack's members.
void stack::print()
{
cout<<"PRINTING STACK\n";
int s=size;
for(int i=0; i<s; i++)
cout<< pop() <<"\n";
}
//Function to determine whether the stack is empty. Returns true for empty.
bool stack::isEmpty()
{
if(size==0)
{
return true;
}
return false;
}
////Class, the instance of which will convert infix to postfix.
class expEvaluator
{
public:
char infix[50];
char postfix[50];
int ps; //counter variable to be used for index of the postfix array.
stack s; //The stack through which the operations will be performed.
expEvaluator() //Constructor.
{
ps=0;
}
bool isOp(char a)//Function to determine whether the character is an operator.
{
if(a=='+' || a=='-' || a=='*' || a=='/' || a=='^' || a=='%' )
return true;
else
return false;
}
bool precedence(char a, char b)//To determine the precedence of operators. True means 'a' is of same or lower precedence than 'b'.
{
if(a=='+' || a=='-')
return true;
else if (a=='*' || a=='/')
{
if(b=='+' || b=='-')
return false;
else if(b=='*' || b=='/')
return true;
}
}
//The function that will convert the given infix statement to postfix.
void convertToPostfix()
{
int l=0; //To keep count of the number of characters entered in infix form.
cout<<"Enter Infix expression: ";
cin>>infix;
for(int i=0; infix[i]!='\0'; i++)
{
l++;
}
for(int i=0; i<l; i++)
{
if(infix[i]=='(')
s.push(infix[i]);
else if(isOp(infix[i])) //If character at infix[i] is an operator
{
while(isOp(s.topstack()) && precedence(infix[i], s.topstack())) //popping operators from stack to postfix array till operator of
{ //lower precedence is met.
postfix[ps]=s.pop();
ps++;
}
s.push(infix[i]); //then push the operator onto the stack.
}
else if(infix[i]==')') //if right bracket encountered.
{
while(s.topstack()!='(') //till left bracket is not encountered,
{
postfix[ps]=s.pop();
ps++; //keep popping elements to postfix array.
}
s.pop(); //pop left bracket when encountered.
}
else //if just an operand is encountered.
{
postfix[ps]=infix[i]; //copy to postfix array.
ps++;
}
}
while(!(s.isEmpty())) //When end of array is reached (the previous loop ends only then) and its not empty,
{
postfix[ps]=s.pop(); //pop all elements from stack onto the postfix array.
ps++;
}
postfix[ps]='\0';
cout << "POSTFIX:\n" << postfix;
}
//Function to calculate the result, when two operands and operator are passed to it.
int calculate(int op1, int op2, char operand)
{
if(operand == '+')
{
return op1 + op2;
}
else if(operand == '-')
{
return op1 - op2;
}
else if(operand == '*')
{
return op1 * op2;
}
else if(operand == '/')
{
return op1 / op2;
}
else if(operand == '%')
{
return op1 % op2;
}
else if(operand == '^')
{
return op1 ^ op2;
}
}
//Function to evaluate the postfix expression:
void evalPfExpression()
{
ps = 0;
while(postfix[ps]!='\0')
{
if (!isOp(postfix[ps]))
{
s.push(postfix[ps]);
ps++;
}
else if(isOp(postfix[ps]))
{//******NOT POPPING CORRECT VALUES.******
int x = s.pop() - 48; //Second operand.
int y = s.pop() - 48; //First operand.
cout << "Second operand: "<< x << " First op:" << y << endl;
int res = calculate(y, x, postfix[ps]); //The result of two operands calculation
s.push(res); //is returned to the variable 'res' and pushed
ps++; //to the stack
}
}
int result = s.pop(); //When '\0' is encountered, loop stops and the final result is popped
cout << "\nThe postfix statement evaluates to:\n" << result << endl;
}
};
//////////////////////////////////////////////////////////////////////////////////
int main(void)
{
expEvaluator e1;
e1.convertToPostfix();
e1.evalPfExpression();
getch();
return 0;
}
Nothing wrong with pop(). It is popping what you are pushing. The problem is with what you are pushing.
If you want values larger than 255 you will have to use 'int', not 'char' as the value type in the node.
You are pushing the character itself, not its value. For example, you are pushing '0', not 0. The difference between them is, guess what? 48.
For multi-digit numbers you need to push the result of some function such as atoi() on the string you want to parse as a number.

Infix to postfix algorithm

I've been working on a algorithm to convert "a+b*c-d/e" to it's postfix form. I've ready the http://en.wikipedia.org/wiki/Shunting-yard_algorithm wiki but am having problem with my logic. When I print out my Queue, I get "a b c d e" with no operators. It seems nothing is getting pushed into my Stack? Or if it is, it isn't getting pushed into my Queue. My Queue / Stack is being implemented by a double linked list class I created.
#include <iostream>
#include "LinkedList.h"
#include "Stack.h"
#include "Queue.h"
using namespace std;
int oper(char c)
{
switch(c) {
case '!':
return 4;
case '*': case '/': case '%':
return 3;
case '+': case '-':
return 2;
case '=':
return 1;
}
return 0;
}
int main () {
LinkedList* list = new LinkedList();
string infix = "a+b*c-d/e";
Stack *holder = new Stack();
Queue *newstring = new Queue();
int length = infix.length();
char temp;
char prev;
for(int i=0; i<length; i++)
{
temp = infix[i];
if((temp == '+') || (temp == '-') || (temp == '*') || (temp == '/'))
{
if (holder->isEmpty())
{
holder->push(temp);
prev = temp;
continue;
}
if(oper(temp)<oper(prev))
{
newstring->queue(holder->popStack());
temp = '\0';
continue;
}
else
holder->push(temp);
prev = temp;
}
else
newstring->queue(temp);
}
while(!holder->isEmpty())
{
newstring->queue(holder->popStack());
}
newstring->printQueue();
return 0;
}
your code part ::
if(oper(temp)<oper(prev))
{
newstring->queue(holder->popStack());
temp = '\0';
continue;
}
this part of the code dosent get a hit at all ......
the string provided in the input "a+b*c-d/e"
see this ::
if(oper(temp)<oper(prev))
the condition is to check the priority of the previous operator with respect to the currently scanned one in the variable temp but there is no statement outside the previous if statement(condition where stack is empty) to extract or assign the prev variable from the options available in the stack hence the initial value of "+" is used for evaluation of the if condition which is less than "*" and "\" , and is at the same level with "-" but not greater as a result the second if condition never gets satisfied and dosent get a hit.
thats probably why when you pop nothing comes out of the stack , and thats how you get your current result. you would need to visit the code again and make appropriate changes.
hope this helps , have a nice day ahead.