I'm currently working on a project converting from postfix to infix using stacks in the form of linked lists. I'm currently trying to read in the whole line as a string then placing it into a character array then when a symbol is found placing one element into a right operand another into a left operand then printing it back out inlcuding the operator. however after placing the first item into the left operand and then popping the stack im not able to place the other item into the right operand. What could be the problem? I its with my pop fucntion.
Here is my code:
#include "stack.h"
stack::~stack()
{
cout<<"Inside !stack \n";
while(s_top != 0)
{
pop();
}
}
void stack::pop()
{
cout<<"Inside pop \n";
stack_node *p;
if (s_top != 0)
{
p = s_top;
s_top = s_top->next;
delete p;
}
}
void stack::push(char a)
{
cout<<"Inside push \n";
stack_node *p = new stack_node;
p->data = a;
p->next = s_top;
s_top = p;
}
void stack::print()
{
cout<<"Inside print \n";
for(stack_node *p = s_top; p!=0; p=p->next)
{
cout<<p->data<<endl;
}
}
stack_element stack::top()
{
cout<<"Inside top \n";
if (s_top == 0)
{
exit(1);
}
else
{
return s_top->data;
}
}
/*stack::stack(const stack & Org)
{
cout<<"Inside the Copy Constructor\n";
stack_node *p=Org.s_top;
(*this).s_top = 0;
while(p!=0)
{
(*this).push(p->data);
p=p->next;
}
}
and here is my cpp where it doesnt completely work
#include "stack.h"
string convert(string expression){
stack c;
string post = " ";
string rightop="";
string leftop="";
string op =" ";
for (int i =0; i<expression.length();i++){
c.push(expression[i]);
if(expression[i]=='*'||'+'||'-'||'/'){
cout<<c.top()<<endl;
leftop=c.top();
c.pop();
rightop=c.top();
cout<<rightop<<endl;
c.pop();
op=c.top();
c.pop();
}
}
}
int main(){
string expression;
cout<<" Enter a Post Fix expression: ";
getline(cin,expression);
convert(expression);
return 0;
}
Here's an issue:
(expression[i]=='*'||'+'||'-'||'/'
This does not do what you think it does.
The fix:
(expression[i] == '*' ||
expression[i] == '+' ||
expression[i] == '-' ||
expression[i] == '/')
Edit 1: Searching strings
Another method is:
char c = expression[i];
const std::string operators="*+-/";
if (operators.find(c) != std::string::npos)
{
// expression[i] is an operator character
}
The commonly posted solution is to use switch:
switch (expression[i])
{
case '+': Process_Operator_Plus(); break;
case '-': Process_Operator_Minus(); break;
case '*': Process_Operator_Multiply(); break;
case '/': Process_Operator_Divide(); break;
}
Remember, you will need to handle operator precedence when evaluating expressions.
Related
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 = 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.
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;
}
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.
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.
I am doing my assignment in which I have to modify my previous task (which is prefix expression tree which takes expression and give result)
+ OR
* AND
- NOT
Now I have to make it Logic expression tree which will perform AND OR and NOT operations
char input;
cin.get(input);
if((input == '+')||(input == '-')||(input == '*'))
{
p = new ExprTreeNode(input,NULL,NULL);
buildSub(p->left);
buildSub(p->right);
}
else if(isdigit(input))
{ //create a new node
p = new ExprTreeNode(input,NULL,NULL);
}
else
{
cout <<" invalid expression exiting..." <<endl;
exit (1);
}
above code reads expression and makes tree using recursion...
I am confused how I can add unary operator that is NOT...
after that I have to evaluate expression
int answer;
switch (p->dataItem){
case '*':
// AND
case'+':
// OR
case '-':
// Reverse
default:
answer = (p->dataItem-'0');
break;
}
return answer;
p is ExprTreeNode
// Data members
char dataItem; // Expression tree data item
ExprTreeNode *left, // Pointer to the left child
*right; // Pointer to the right child
I'd say you want to do the following:
if ((input == '+') || (input == '*'))
{
p = new ExprTreeNode(input,NULL,NULL);
buildSub(p->left);
buildSub(p->right);
}
else if (input == '-')
{
p = new ExprTreeNode(input, NULL, NULL);
buildSub(p->left);
}
else if(isdigit(input))
{ //create a new node
p = new ExprTreeNode(input,NULL,NULL);
}
else
{
cout <<" invalid expression exiting..." <<endl;
exit (1);
}
Edit:
Then, the evaluation routine could work like this:
bool ExprTreeNode::evaluate() {
switch (dataItem) {
case '+':
return left->evaluate() || right->evaluate();
case '*':
return left->evaluate() && right->evaluate();
case '-':
return !left->evaluate();
case '0':
return false;
default:
return true;
}
}