My goal is to convert infix expression to postfix expression.
I've got a problem with this line:
while(precedence(stack[top])>=precedence(symbol))
Condition is (and should be) satisfied when it is ++ or ** or / or -- because it checks from left, but in case of power(^) it begins from the right. I don't want to enter this loop if it is doubled power(^^).
in simple in while(precedence(stack[top])>=precedence(symbol)) if the operator in top is (^)and operator in symbol is (^)I do not want to enter while loop I will remove this case because it is wrong, but I didn't know how.
C++:
#include<iostream>
#include<stdio.h>
using namespace std;#
define size 100
int temp, length = 0, inx = 0, pos = 0, top = -1;
char symbol, infix[size], postfix[size], stack[size];
void push(char);
char pop();
int precedence(char);
void infix_to_postfix(char[]);
void push(char symbol) {
if (top >= size - 1) {
cout << "stack is over flow push not possible" << endl;
} else {
top = top + 1;
stack[top] = symbol;
}
}
char pop() {
temp = stack[top];
top = top - 1;
return temp;
}
int precedence(char symbol) {
int priority = 0;
switch (symbol) {
case '+':
case '-':
priority = 1;
break;
case '*':
case '/':
priority = 2;
break;
case '^':
priority = 3;
break;
} //end of switch()
return priority;
} //end of precedence()
void infix_to_postfix(char infix[]) {
while (infix[inx] != '\0') {
symbol = infix[inx++];
switch (symbol) {
case '(':
push(symbol);
break;
case ')':
temp = pop();
while (temp != '(') {
postfix[pos++] = temp;
temp = pop();
}
break;
case '-':
case '+':
case '*':
case '/':
case '^':
while (precedence(stack[top]) >= precedence(symbol)) {
temp = pop();
postfix[pos++] = temp;
}
push(symbol);
break;
default:
postfix[pos++] = symbol;
break;
}
}
while (top > -1) {
temp = pop();
postfix[pos++] = temp;
postfix[pos] = '\0';
}
}
int main() {
cout << "\nEnter an infix expression:\n";
cin >> infix;
infix_to_postfix(infix);
cout << "\nThe equivalent postfix expression:\n";;
cout << postfix << endl;;
return 0;
}
in simple in while(precedence(stack[top])>=precedence(symbol)) if the operator in top is (^)and operator in symbol is (^)I do not want to enter while loop
Use
while (precedence(stack[top]) >= precedence(symbol) && stack[top] != '^' && symbol != '^')
Adding an && to your condition will make it check that both the operator at the top of the stack and the symbol isn't '^'.
You could also do
// ...
case '^':
if (stack[top] != '^' && symbol != '^')
while(precedence(stack[top])>=precedence(symbol))
{
temp=pop();
postfix[pos++]=temp;
}
// ...
Related
I am getting error for no operator "==" matches these operands -- operand types are: info == charC/C++(349)
I guess this is due to the fact im using couston data type
I making program to solve the reverse polish eqaution.I thoght I will store in polish eqation in stack and then sort the inputs into two segments. In two diffrent stacksbut it turns out it is not possible.
using namespace std;
union info
{
char ch;
float num;
};
struct node{
info data;
node *link;
node(info x){
data=x;
link= NULL;
}
}*st;
struct rst{
float data;
rst *link;
rst(float x){
data=x;
link= NULL;
}
}*rs;
void insertxp(info num,struct node *head){
node *new_node;
new_node=new node(num);
new_node->link=head->link;
head->link=new_node;
}
void insertrst(float x,rst *head){
rst *new_p;
new_p = new rst(x);
new_p->link=head->link;
head->link=new_p;
}
void del(rst *head){
rst *temp;
temp = head;
head = head->link;
delete temp;
}
bool checkop(info ch){
if (ch == '+' ||ch=='-'||ch=='*'||ch=='/'||ch=='^')
return true;
else
return false;
}
float eval(float a,float b,char ch){
switch (ch)
{
case '+':
return a+b ;
break;
case '-':
return a-b;
break;
case '*':
return a*b;
break;
case '/':
return a/b;
break;
case '^':
double c,d;
c=(int)a;
d=(int)b;
return pow(c,d);
break;
default:
break;
}
}
float calc(node *head,rst *rsthead){
insertxp(')',*head);
node *ptr = head;
info curr;
float a=0,b=0,num=0;
for (int i = 0;; i++)
{ curr = ptr->data;
if(checkop(curr)==true)
{ if (curr == ')')
{
break;
}
a=rsthead->data;
b=rsthead->link->data;
num=eval(a,b);
del(rsthead);
del(rsthead);
insertrst(num,rsthead);
}
else
{
insertrst(curr);
}
}
if (rsthead->link->data=!NULL)
{
cout << "Invalid Polish Expression!!!\n";
}
return rsthead->data;
}
int main(){
info x;
cout << "Enter your Exoression and press B when you completly entred your post fix expression \n";
for (int i = 0; i < 100; i++)
{
cin >> x;
if (x == 'B')
{
break;
}
insertxp(x,st);
}
cout << "Expression Succfully Entred \n";
}```
The error message is telling you that you can't directly compare a union info with a char.
What you can do, though, is compare the field ch of a union info, which is of type char, with another char.
Hence, replace:
curr == ')' with curr.ch == ')';
ch == '+' ||ch=='-'||ch=='*'||ch=='/'||ch=='^' with ch.ch == '+' ||ch.ch == '-'||ch.ch == '*'||ch.ch =='/'||ch.ch=='^';
cin >> x with cin >> x.ch.
I also strongly discourage you from writing using namespace std at the beginning of your file. About this you can read: Why is “using namespace std;” considered bad practice?
this is data structure (stack) question. in c++. (no use STL)
i want input Infix Formula file(txt, if there is not file, input is user's typing.)
and convert Postfix Formula, then caculate formula.
how can i input Postfix Formula in caculate fuction ?
i try make file and read file, but is not work. (i try change endl position(delete), also not work.)
ArrayStack.h
#include <iostream>
#include <cstdlib>
#define _CRT_SECURE_NO_WARNINGS
using namespace std;
inline void error(const char *message)
{
cout << message << endl;
exit(1);
}
const int MAX_STACK_SIZE = 20;
class ArrayStack
{
private:
int top;
int data[MAX_STACK_SIZE];
public:
ArrayStack()
{
top = -1;
}
~ArrayStack()
{
}
bool isEmpty()
{
return top == -1;
}
bool isFull()
{
return top == MAX_STACK_SIZE - 1;
}
void push(int e)
{
if (isFull())
error("스택 포화 에러");
data[++top] = e;
}
int pop()
{
if (isEmpty())
error("스택 공백 에러");
return data[top--];
}
int peek()
{
if (isEmpty())
error("스택 공백 에러");
return data[top];
}
void display()
{
printf("[스택 항목의 수 = %2d] ==> ", top + 1);
for (int i = 0; i < top; i++)
printf("<%2d>", data[i]);
printf("\n");
}
};
pg1_stack.cpp
#pragma warning(disable:4996)
#include "ArrayStack.h"
#include <string.h>
#include <fstream>
inline static int precedence(char op)
{
switch (op) {
case '(': case ')': return 0;
case '+': case '-': return 1;
case '*': case '/': return 2;
}
return -1;
}
void infixToPostfix(FILE *fp = stdin)
{
char c, op;
double val;
ArrayStack stack;
ofstream os;
os.open("stack_Data.txt");
while ((c = getc(fp)) != '\n')
{
if ('0' <= c && c <= '9')
{
ungetc(c, fp);
fscanf_s(fp, "%lf", &val);
printf("%4.1f ", val);
os << val;
}
else if (c == '(')
stack.push(c);
else if (c == ')')
{
while (!stack.isEmpty())
{
op = stack.pop();
if (op == '(') break;
else
printf("%c ", op);
os << op;
}
}
else if (c == '+' || c == '-' || c == '*' || c == '/')
{
while (!stack.isEmpty())
{
op = stack.peek();
if (precedence(c) <= precedence(op))
{
printf("%c ", op);
os << op;
stack.pop();
}
else break;
}
stack.push(c);
}
}
while (!stack.isEmpty()) {
char c2 = stack.pop();
os << c2;
printf("%c ", c2);
}os << endl;
os.close();
printf("\n");
}
double calcPostfixExpr(const char *filename)
{
FILE *fp = fopen(filename, "r");
if (fp == NULL)
error("Error: 파일 존재하지 않습니다.\n");
char ch;
ArrayStack stack;
while ((ch = getc(fp)) != '\n')
{
if (ch == '+' || ch == '-' || ch == '*' || ch == '/')
{
double right = stack.pop();
double left = stack.pop();
switch (ch) {
case '+':
stack.push(left + right);
break;
case '-':
stack.push(left - right);
break;
case '*':
stack.push(left * right);
break;
case '/':
stack.push(left / right);
break;
}
}
else if ('0' <= ch && ch <= '9')
{
ungetc(ch, fp);
double val;
fscanf_s(fp, "%lf", &val);
stack.push(val);
}
}
fclose(fp);
return stack.pop();
}
void main() {
infixToPostfix();
double res = calcPostfixExpr("stack_Data.txt");
printf("%f", res);
system("Pause");
}
this is before try make file and read file way
#pragma warning(disable:4996)
#include "ArrayStack.h"
#include <string.h>
#include <fstream>
inline static int precedence(char op)
{
switch (op) {
case '(': case ')': return 0;
case '+': case '-': return 1;
case '*': case '/': return 2;
}
return -1;
}
void infixToPostfix(FILE *fp = stdin)
{
char c, op;
double val;
ArrayStack stack;
while ((c = getc(fp)) != '\n')
{
if ('0' <= c && c <= '9')
{
ungetc(c, fp);
fscanf_s(fp, "%lf", &val);
printf("%4.1f ", val);
}
else if (c == '(')
stack.push(c);
else if (c == ')')
{
while (!stack.isEmpty())
{
op = stack.pop();
if (op == '(') break;
else
printf("%c ", op);
}
}
else if (c == '+' || c == '-' || c == '*' || c == '/')
{
while (!stack.isEmpty())
{
op = stack.peek();
if (precedence(c) <= precedence(op))
{
printf("%c ", op);
stack.pop();
}
else break;
}
stack.push(c);
}
}
while (!stack.isEmpty()) {
char c2 = stack.pop();
printf("%c ", c2);
}
printf("\n");
}
double calcPostfixExpr(FILE* fp = stdin)
{
char ch;
ArrayStack stack;
while ((ch = getc(fp)) != '\n')
{
if (ch == '+' || ch == '-' || ch == '*' || ch == '/')
{
double right = stack.pop();
double left = stack.pop();
switch (ch) {
case '+':
stack.push(left + right);
break;
case '-':
stack.push(left - right);
break;
case '*':
stack.push(left * right);
break;
case '/':
stack.push(left / right);
break;
}
}
else if ('0' <= ch && ch <= '9')
{
ungetc(ch, fp);
double val;
fscanf_s(fp, "%lf", &val);
stack.push(val);
}
}
return stack.pop();
}
void main() {
infixToPostfix();
system("Pause");
}
I've got a few different functions that on their own work fine. Now I am trying to put them together into one file. My debugger is throwing segmentation faults in the infixToPostfix function.
When I watch the ns variable, it does not show anything getting assigned to it, but it prints out the postfix expression when I actually run the code. When ns passes into PostfixEvaulation, it runs to the top member function of TemplateStack and crashes with:
terminate called after throwing an instance of "std::string"
This only happens when I pass a string with an operator. When I pass a string of just numbers, everything runs fine,
but it still does not seem to call PostfixEvaluation.
#include <iostream>
#include <sstream>
#include <string>
#include <typeinfo>
using namespace std;
//Class Template Stack declaration
template <class T>
class TemplateStack {
public:
typedef T type;
TemplateStack()
{
max_size_ = 50;
TopOfStack = 0;
data_ = new T[max_size_];
} //Default Constructor taking no parameters
void push(T element)
{
if (TopOfStack == max_size_)
throw string("Stack's underlying storage is overflow");
TopOfStack++;
data_[TopOfStack] = element;
}
void pop() {
if (TopOfStack == -1)
throw string("Stack is empty");
TopOfStack--;
}
T top() {
if (TopOfStack == -1)
throw string("Stack is empty");
return data_[TopOfStack];
}
private:
int TopOfStack; //Generic data type for the top element of stack
size_t max_size_;
T* data_;
};
//Function to Evauluate the Postfix notation expresion
int PostfixEvaulation(string input){
//string input;
int operand1, operand2, result,number;
TemplateStack<char>operation;
stringstream temp;
int i=0;
while (i < input.length())
{
if (isdigit(input[i]))
{
operation.push(input[i]);
}
else
{
operand2 = operation.top();
temp << operation.top();
operation.pop();
operand1 = operation.top();
temp << operation.top();
operation.pop();
switch(operand1,operand2)
{
case '+': result=operand1 + operand2;
break;
case '-': result=operand1 - operand2;
break;
case '*': result=operand1 * operand2;
break;
case '/': result=operand1 / operand2;
break;
}
operation.push(result);
}
i++;
}
cout << "The result is: "<<temp.str()<<endl;
//cin.ignore(numeric_limits<streamsize>::max(), '\n');
return 0;
}
//Function to return precedence of operators
int prec(char c)
{
if(c == '^')
return 3;
else if(c == '*' || c == '/')
return 2;
else if(c == '+' || c == '-')
return 1;
else
return -1;
}
//Function: Convert Infix to Postfix
void infixToPostfix(string s)
{
TemplateStack<char> st;
st.push('N');
int l = s.length();
string ns;
for (int i = 0; i < l; i++) {
// If the scanned character is an operand, add it to output string.
if ((s[i] >= 'a' && s[i] <= 'z') || (s[i] >= 'A' && s[i] <= 'Z')) {
ns += s[i];
}
// If the scanned character is an ‘(‘, push it to the stack.
else if (s[i] == '(') {
st.push('(');
}
// If the scanned character is an ‘)’, pop and to output string from the stack
// until an ‘(‘ is encountered.
else if (s[i] == ')') {
while (st.top() != 'N' && st.top() != '(') {
char c = st.top();
st.pop();
ns += c;
}
if (st.top() == '(') {
char c = st.top();
st.pop();
}
}
//If an operator is scanned
else {
while (st.top() != 'N' && prec(s[i]) <= prec(st.top())) {
char c = st.top();
st.pop();
ns += c;
}
st.push(s[i]);
}
}
//Pop all the remaining elements from the stack
while (st.top() != 'N') {
char c = st.top();
st.pop();
ns += c;
}
cout << "Here is the ns variable: "<< ns << endl;
PostfixEvaulation(ns);//Call the PostFixEvaluationFunction with the ns (postfix notation) variab
}
//Function: User inputs Expression
void GetInput(){
string input;
cout << "Enter Infix Expression: ";
getline(cin, input);
infixToPostfix(input);
}
int main()
{
GetInput();
}
Implement C++ program for expression conversion as infix to postfix and its evaluation using stack based on given conditions
Operands and operator, both must be single character.
Input Postfix expression must be in a desired format.
Only '+', '-', '*' and '/ ' operators are expected
I do not understand what is the importance of push(po[i]-'0') statement in the function evaluate()
#include<iostream>
using namespace std;
class stack
{
char st[20],in[20],po[20];
int TOP,k;
public:
stack()
{
TOP=-1;
k=0;
}
void infixToPostfix();
void evaluate();
private:
void push(char);
char pop();
int precedence(char);
};
void stack::push(char ch)
{
if(TOP==19)
{
cout<<"Stack overflow"<<endl;
}
else
{
TOP++;
st[TOP]=ch;
}
}
char stack::pop()
{
if(TOP==-1)
{
cout<<"Stack underflow"<<endl;
return 0;
}
else
{
int m=st[TOP];
TOP--;
return m;
}
}
void stack::evaluate()
{
cout<<"The postfix expression is"<<endl<<po<<endl;;
int a,b,res,temp;
TOP=-1;
for(int i=0;po[i]!='\0';i++)
{
if(isdigit(po[i])==1)
{
push(po[i]-'0');
}
else
{
a=pop();
b=pop();
switch(po[i])
{
case '+': res=b+a;
break;
case '-': res=b-a;
break;
case '*': res=b*a;
break;
case '/': res=b/a;
break;
}
push(res);
}
}
temp=pop();
cout<<"The answer is "<<temp<<endl;
}
void stack::infixToPostfix()
{
int m;
char left='(',right=')';
cout<<"Enter infix expression"<<endl;
cin>>in;
for(int i=0;in[i]!='\0';i++) //if operand add it to postfix
{
if(isalpha(in[i])==1 || isdigit(in[i]==1))
{
po[k]=in[i];
k++;
}
else if(in[i]==left) //if left parenthesis then push it to stack;
{
push(left);
}
else if(in[i]==right) //if right parenthesis encountered then pop from stack until left parenthesis
{
while((m=pop())!=left)
{
po[k]=m;
k++;
}
}
else //if operator is encounterd pop from the stack the operands having equal or higher precedence
{
while(precedence(st[TOP])>=precedence(in[i]))
{
int m=pop();
po[k]=m;
k++;
}
push(in[i]);
}
}
while(TOP>=0)
{
po[k]=pop();
k++;
}
po[k]='\0';
cout<<"The postfix expression is"<<endl;
cout<<po;
}
int stack::precedence(char ch)
{
if(ch=='+' || ch=='-')
{
return 1;
}
else if(ch=='*' || ch=='/')
{
return 2;
}
else if(ch=='(')
{
return 0;
}
}
int main()
{
stack s;
int op;
do
{
cout<<"\n____________________________"<<endl;
cout<<"1 Postfix to infix conversion"<<endl;
cout<<"2 Evaluation of postfix"<<endl;
cout<<"3 Exit"<<endl;
cout<<"______________________________"<<endl;
cin>>op;
switch(op)
{
case 1: s.infixToPostfix();
break;
case 2: s.evaluate();
break;
case 3:break;
default: cout<<"Enter correct option"<<endl;
}
}while(op!=3);
return 0;
}
It converts the digit character into digit(integer). for e.g.
if po[i] = '5'.
It pushes, '5'-'0' => 53-48 (their ascii values) = 5.
cheers.
The program should read a postfix expression consisting of numbers and operators and compute the result. I try using string but I keep getting a result that is way off. Can you please tell me what I'm doing wrong?
#include <iostream>
#include "StackADT.h"
#include <stack>
using namespace std;
#include <string>;
bool isOperator(string);
int calculate (int, char, int);
void display (int, string, int, int);
int main(){
string expr;
int operand2 = 0;
int operand1 = 0;
string thisOperator;
int value;
int result;
cout << "Evaluates a postfix expression(to Quit)." << endl;
cin >> expr;
//while(expr != "-1")
{
//getline( cin, expr,'\n' );
int exprSize = expr.size();
const int siz = 10;
char expr2[siz];
for (int i = 0; i < expr.length; i++)
{
expr2[i] = expr[i];
}
Stack<int> stack;
int index = 0;
while (index < exprSize){
if (!isOperator(expr[index]) )
{
stack.pushStack(expr[index]);
}
else
{
stack.popStack (operand2);
stack.popStack (operand1);
thisOperator = expr[index];
value = calculate (operand1, thisOperator[index], operand2);
stack.pushStack(value);
}
index++;
}
result = stack.popStack (operand1);
display(operand1, thisOperator, operand2, result );
// cout << "Evaluates a postfix expression(to Quit)." << endl;
// cin >> expr;
}
system("pause");
return 0;
}
void display (int op1, string operat, int op2, int result){
cout << op1 << operat << op2 << " = " << result;
}
bool isOperator(char token )
{
if(token == '-' || token == '+' || token == '*' || token == '/')
return true;
else
return false;
}
int calculate (int op1, char operat, int op2){
switch (operat)
{
case '/': return op1 / op2;
break;
case '+': return op1 + op2;
break;
case '*': return op1 * op2;
break;
case '-': return op1 - op2;
break;
default: cout << "Cant / by zero" << endl;
break;
}
}
I'm working off this; exprSize = length of string
createStack (stack)
index = 0
loop (index < exprSize)
if (expr[index] is operand)
pushStack (stack, expr[index])
else // expr[index] is an operator
popStack (stack, operand2)
popStack (stack, operand1)
operator = expr[index]
value = calculate (operand1, operator, operand2)
pushStack (stack, value)
end if
index = index + 1
end loop
popStack (stack, result)
return (result)