How can i print this caculation? -DS stack question - c++

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");
}

Related

infix to postfix program not producing the correct output

#include <iostream>
#include <string>
#include <vector>
#include <sstream>
#include <iomanip>
using namespace std;
class Stack {
public:
string stack[100][1];
int size;
Stack() { size = 0; }
~Stack() {};
void push(string data) {
stack[size][0] = data;
size += 1;
}
bool empty() {
if (size == 0)
{
return true;
}
else
{
return false;
}
}
string pop() {
size -= 1;
return stack[size][0];
}
string top() {
if (empty())
cout << "Stack is empty";
return stack[size - 1][0];
}
};
int pre(char op)
{
switch (op)
{
case '(': case ')': return 0;
case '+': case '-': return 1;
case '*': case '/': return 2;
}
return -1;
}
vector<string> infix_to_postfix(const vector<string>& expr) {
vector<string> postfix;
string op;
Stack st;
for (int i = 0; i < expr.size(); i++) {
if (expr[i][0] == '+' || expr[i][0] == '-' || expr[i][0] == '*' || expr[i][0] == '/') {
while (!st.empty()) {
op = (st.top()[0]);
if (pre(expr[i][0]) <= pre(op[0]))
postfix.push_back(st.pop());
else break;
}
postfix.push_back(expr[i]);
}
else if (expr[i][0] == '(') {
st.push(expr[i]);
}
else if (expr[i][0] == ')') {
while (!st.empty()) {
op = st.pop();
if (op[0] == '(') break;
else {
postfix.push_back(op);
}
}
}
else {
postfix.push_back(expr[i]);
}
}
return postfix;
}
int main() {
auto expr = infix_to_postfix({ "(", "2", "+", "3", ")", "*", "7" });
for (auto& elem : expr)
{
std::cout << elem << ", ";
}
std::cout << "\n";
return 0;
}
This program is supposed to convert from infix to postfix but it is not producing the correct output. I'm expecting the output to be:
2, 3, +, 7, *,
but the output is
2, +, 3, *, 7,
You have two issues.
When handling an operator, after popping the lower precedence operators you need to push the new operator onto the stack rather than adding it to the result:
if (expr[i][0] == '+' || expr[i][0] == '-' || expr[i][0] == '*' || expr[i][0] == '/') {
while (!st.empty()) {
op = (st.top()[0]);
if (pre(expr[i][0]) <= pre(op[0]))
postfix.push_back(st.pop());
else break;
}
st.push(expr[i]);
}
At the end of the function you need to pop any remaining operators off the stack:
while (!st.empty())
{
postfix.push_back(st.pop());
}
return postfix;

Link error when compiling basic assembler

I was trying to create a special assembler that will run with a specific machine type. I was trying to compile the program, but got a linker error:
/usr/bin/ld: lexer.o: in function `Lexer::lex(std::__cxx11::basic_string, std::allocator >)':
lexer.cpp:(.text+0x2ee): undefined reference to `Lexer::isSpecial(char)'
collect2: error: ld returned 1 exit status
Screenshot here
I have 3 main files: lexer.h, lexer.cpp, sasm.cpp. Here's the code.
lexer.h:
#ifndef LEXER_H
#define LEXER_H
#include <iostream>
#include <vector>
// type definitions
typedef uint8_t byte;
typedef std::vector<std::string> strings;
enum State : byte {
START,
READCHAR,
READBLOCK,
SKIP,
DUMP,
COMMENT,
END
};
// Instructions definitions
#define ADD 0x40000001
#define SUB 0x40000002
#define TIME 0x40000003
#define DIVIDE 0x40000004
#define HALT 0x40000000
class Lexer {
private:
bool isSpace(char c);
bool isSpecial(char c);
bool isGroup(char c);
char end_char, beg_char;
public:
strings lex(std::string s);
};
#endif
lexer.cpp:
#include "lexer.h"
strings Lexer::lex(std::string s) {
strings strLst;
char lexEme[256];
int i = 0;
int j = 0;
State state = START;
int done = 0;
int len = s.length();
int balance = 0;
while (i < len) {
switch (state) {
case START:
if (isSpace(s[i])) {
state = SKIP;
} else if (isGroup(s[i])) {
if (s[i] == '"') {
lexEme[j] = s[i];
j++;
i++;
}
state = READBLOCK;
} else if (s[i] == '/' && s[i + 1] == '/') {
i += 2;
state = COMMENT;
} else {
state = READCHAR;
}
break;
case READCHAR:
if (isSpace(s[i])) {
state = DUMP;
} else if (s[i] == '\\') {
i += 2;
} else if (isGroup(s[i])) {
if (s[i] == '"') {
lexEme[j] = s[i];
j++;
i++;
}
state = READBLOCK;
} else if (isSpecial(s[i])) {
if (j == 0) {
lexEme[j] = s[i];
j++;
i++;
}
state = DUMP;
} else if (s[i] == '/' && s[i + 1] == '/') {
i += 2;
state = COMMENT;
} else {
lexEme[j] = s[i];
j++;
i++;
}
break;
case READBLOCK:
if (s[i] == beg_char && s[i] != '"') {
balance++;
lexEme[j] = s[i];
j++;
i++;
} else if (s[i] == end_char) {
balance--;
lexEme[j] = s[i];
j++;
i++;
if (balance <= 0) {
state = DUMP;
}
} else if (end_char == '"' && s[i] == '\\') {
// TODO: fix this to actually record the chars
i += 2;
} else {
lexEme[j] = s[i];
j++;
i++;
}
break;
case SKIP:
if (isSpace(s[i])) {
i++;
} else {
state = READCHAR;
}
break;
case DUMP:
if (j < 0) {
lexEme[j] = 0;
strLst.push_back(lexEme);
j = 0;
}
state = START;
break;
case COMMENT:
if (s[i] != '\n') {
i++;
} else {
state = READCHAR;
}
break;
case END:
i = len;
break;
}
}
if (j > 0) {
lexEme[j] = 0;
strLst.push_back(lexEme);
}
return strLst;
}
// This function allows us what a space is
bool Lexer::isSpace(char c) {
switch (c) {
case '\n':
case '\r':
case '\t':
case '\v':
case ' ':
case '\f':
return true;
default:
return false;
}
}
bool Lexer::isGroup(char c) {
beg_char = c;
switch (c) {
case '"':
end_char = '"';
return true;
case '(' :
end_char = ')';
return true;
case ')':
return true;
default:
return false;
}
}
bool isSpecial(char c) {
switch (c) {
case '[':
case ']':
return true;
default:
return false;
}
}
sasm.cpp:
#include <fstream>
#include "lexer.h"
typedef uint32_t i32;
using namespace std;
vector<i32> compile(strings s);
bool isInteger(string s);
bool isPrimitive(string s);
i32 mapToNumber(string s);
int main (int argc, char* argv[]) {
// Check for input errors
if (argc != 2) {
cerr << "Usage: " << argv[0] << " <sasm-file>" << endl;
exit(1);
}
// Read input file
ifstream infile;
infile.open(argv[1]);
if (!infile.is_open()) {
cerr << argv[1] << ": file can't be found" << endl;
exit(1);
}
string line;
string contents;
while (getline(infile, line)) {
contents += line + "\n";
}
infile.close();
// Parse infile
Lexer lexer;
strings lexEmes = lexer.lex(contents);
// Compile binary
vector<i32> instructions = compile(lexEmes);
// Write instructions to file
ofstream ofile;
ofile.open("out.bin", ios::binary);
for (i32 i = 0; i < instructions.size(); i++) {
ofile.write(reinterpret_cast<char*>(&instructions[i]), sizeof(i32));
}
ofile.close();
return 0;
}
vector<i32> compile(strings s) {
vector<i32> instructions;
for (i32 i = 0; i < s.size(); i++) {
if (isInteger(s[i])) {
instructions.push_back(stoi(s[i]));
} else {
i32 instruction = mapToNumber(s[i]);
if (instruction != -1) {
instructions.push_back(instruction);
} else {
cerr << "\033[1;31m" << s[i] << "\033[0m Invalid instruction" << std::endl;
}
}
}
return instructions;
}
bool isInteger(string s) {
for (i32 i = 0; i < s.length(); i++) {
if (!isdigit(s[i])) {
return false;
}
}
return true;
}
i32 mapToNumber(string s) {
if (s == "+") {
return ADD;
} else if (s == "-") {
return SUB;
} else if (s == "*") {
return TIME;
} else if (s == "/") {
return DIVIDE;
}
return -1; // Invalid instruction
}
Thanks for your answers.
You are missing the class reference in the function definition.
bool Lexer::isSpecial(char c)
^^^^^^^

Infix/Postfix evaluator terminating issue

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();
}

Conversion of infix to postfix: stack is not recognized error

I am a beginner using the stack so I been trying to do different exercises on it. I'm trying to convert infix->postfix. The xcode debugger says "Use of class template 'stack'requires template arguments'. Here is my code.
#include<iostream>
#include<stack>
#include<string>
using namespace std;
bool IsOperand(char ch)
{
if ((ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z')) {
return true;
}
return false;
}
bool IsOperator(char C)
{
if (C == '+' || C == '-' || C == '*' || C == '/' || C == '^') {
return true;
}
return false;
}
bool IsLeftParenthesis(char ch)
{
if (ch == '(') {
return true;
}
return false;
}
bool IsRightParenthesis(char ch)
{
if (ch == ')') {
return true;
}
return false;
}
bool Flag(char ch)
{
if (!IsOperand(ch) || !IsOperator(ch) || !IsLeftParenthesis(ch) || !IsRightParenthesis(ch)) {
return false;
}
return true;
}
int IsRightAssociative(char op)
{
if (op == '^') {
return true;
}
return false;
}
int GetOperatorWeight(char op)
{
int weight = -1;
switch (op) {
case '+':
case '-':
weight = 1;
break;
case '*':
case '/':
weight = 2;
break;
case '^':
weight = 3;
break;
}
return weight;
}
bool 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.
// BUT REMEMBER...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;
}
string InfixToPostfix(string expression)
{
stack S;
string postfix = "";
for (auto& elem : expression) {
if (Flag(elem)) {
continue;
}
// If character is operator, pop two elements from stack, perform operation and push the result back.
else if (IsOperator(elem)) {
while (!S.empty() && S.top() != '(' && HasHigherPrecedence(S.top(), elem)) {
postfix += S.top();
S.pop();
}
S.push(elem);
}
else if (IsOperand(elem)) {
postfix += elem;
}
else if (elem == '(') {
S.push(elem);
}
else if (elem == ')') {
while (!S.empty() && S.top() != '(') {
postfix += S.top();
S.pop();
}
S.pop();
}
}
while (!S.empty()) {
postfix += S.top();
S.pop();
}
return postfix;
}
int main()
{
// std::string expression = "54/(5^2)+(6^2^3)";
std::string expression = "A+(BC-(D/E^F)G)H";
std::string postfix = InfixToPostfix(expression);
std::cout << "Output = " << postfix << "\n";
}
Here specificially where the error is happening.
string InfixToPostfix(string expression)
{
stack S;
It says
Stack S -> Use of class template 'stack'requires template arguments'
Stack is a container, you need to specify the type of the container like:
stack <int> S;
or in you case it is stack of char:
stack <char> S;

Binary Operads sample program

Problem Statement :
Write a C++ program to evaluate postfix expressions. Your program should take postfix expression as an input, process it with the help of stack and display the result after performing required calculations.
Only following Binary operators are allowed for this program:
+, -, *, /, ^ [addition, subtraction, multiplication, division, exponentiation]
If some error occurs while processing postfix expression, your program should display a meaningful message, like:
Error: Division by zero not allowed
Error: Two operands required for __ operator
Error: Invalid postfix expression
Help me with it, My program is generating errors This is my try:
#include<iostream>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<string>
#define MAX_SIZE 20
using namespace std;
template<class T>
class Stack
{
private:
T item[MAX_SIZE];
int top;
public:
Stack()
{
top = -1;
}
void push(T data)
{
if(!this->is_full())
item[++top] = data;
else
{
cout<<"Stack Error"<<endl;
exit(10);
}
}
T pop()
{
if(!this->is_empty())
return item[top--];
else
{
cout<<"Stack is Empty"<<endl;
exit(11);
}
}
int size()
{
return top+1;
}
bool is_empty()
{
if(top==-1)
return true;
else
return false;
}
bool is_full()
{
if(top==MAX_SIZE-1)
return true;
else
return false;
}
void display()
{
for(int i=0; i<this->size(); i++)
{
cout<<item[i]<<" ";
}
cout<<endl;
}
T return_top()
{
return item[top];
}
};
class Convert
{
private:
bool num_flag;
bool tow_digit_flag;
public:
Convert();
string return_with_bracket(string infix);
void to_Postfix(string infix,char postfix[]);
bool prcd(char op1, char op2);
int isOperand(char op);
int isOperator(char op);
bool return_flag()
{
return num_flag;
}
};
Convert::Convert()
{
this->num_flag = false;
this->tow_digit_flag = false;
}
string Convert::return_with_bracket(string infix)
{
return("(" + infix + ")");
}
bool Convert::prcd(char op1, char op2)
{
if((op1=='+' || op1=='-' || op1=='*' || op1=='/') && op2=='(' )
return true;
if(op1=='+' && op2=='+')
return true;
if(op1=='-' && op2=='-')
return false;
if(op1=='-' && op2=='+')
return false;
if(op1=='+' && op2=='-')
return false;
if(op1=='/' && op2=='/')
return false;
if(op1=='/' && (op2=='-' || op2=='+'))
return true;
if(op1=='*' && (op2=='+' || op2=='-'))
return true;
if((op1 == '-' || op1 == '+') && (op2 =='*' || op2 == '/'))
return false;
if((op1=='$' || op1 == '+') && (op2 =='*' || op2 == '/' || op2=='-'))
return true;
if((op1 == '-' || op1 == '+' || op1 =='*' || op1 == '/')&& op2=='^')
return false;
if(op1 == '^' && ( op2 == '+' || op2 =='*' || op2 == '/' || op2=='-'))
return false;
}
int Convert::isOperand(char op)
{
return(op>= '0' && op <= '9');
}
int Convert::isOperator(char op)
{
return(op=='+' || op=='-' || op == '/' || op=='*' || op=='^');
}
void Convert::to_Postfix(string infix, char postfix[])
{
int position, outpos=0;
char c;
int count = 0;
char temp;
char stacktop ;
Stack<char> stack;
for(position = 0; (c = infix[position])!='\0'; position++)
{
if(this->isOperand)
{
postfix[outpos++] = c;
this->num_flag = true;
count++;
if(count>=2)
{
this->tow_digit_flag = true;
}
}
else if(this->isOperator©)
{
count = 0;
if(isOperator(infix[position]) && isOperator(infix[position+1]))
{
cout<<"\aMissing argument in between "<<infix[position]<<" and "<<infix[position+1]
<<" in column "<< position+1<<endl;
exit(9);
}
if(this->prcd(c, stacktop))
{
stacktop=stack.return_top();
stack.push©;
stacktop = c;
}
else
{
while(true)
{
temp = stack.pop();
postfix[outpos++] =temp;
stacktop = stack.return_top();
if(prcd(c, stacktop) || stacktop=='(')
break;
}
stack.push©;
stacktop = stack.return_top();
}
}
else if(c=='(')
{
count = 0;
stack.push©;
stacktop = stack.return_top();
}
else if(c==')')
{
count = 0;
while(1)
{
if(stack.size()==0)
{
cout<<"Warning!! Number of ')' is greater than '('" <<endl;
exit(2);
}
temp = stack.pop();
if(temp!='(')
{
postfix[outpos++] = temp;
}
else
{
break;
}
}
stacktop =stack.return_top();
}
else
{
cout<<"Invalid input";
exit(3);
}
if(infix[position]==')' && infix[position+1]=='(')
{
stack.push('*');
stacktop = stack.return_top();
}
}
if(stack.size()!=0)
{
cout<<"Warning!!Number of '(' is greater than ')'"<<endl;
// exit(6);
}
if(!this->return_flag())
{
cout<<"You must Enter Numeric value for calculation"<<endl;
cout<<"This program cannot perform operations on variables";
exit(5);
}
if(this->tow_digit_flag)
{
cout<<"Sory! Althoug u may have entered right string"<<endl;
cout<<"this program is only for single digit operation"<<endl;
exit(8);
}
postfix[outpos] = '\0';
}
class Evaluate
{
public:
double eval(char expr[], Convert &Wink;
double oper(int symb, double op1, double op2);
};
double Evaluate::oper(int symb, double op1, double op2)
{
switch(symb)
{
case '+':
return (op1 + op2);
case '-':
return (op1 - op2);
case '*':
return (op1 * op2);
case '/':
return (op1 / op2);
case '^':
return (pow(op1, op2));
}
}
double Evaluate::eval(char expr[],Convert &convert)
{
int c, position;
char temp1;
int count = 0;
double opnd1, opnd2, value;
Stack<double> stack;
for(position = 0; (c = expr[position])!='\0'; position++)
{
if(convert.isOperand©)
{
temp1 = double(c-'0');
stack.push(temp1);
}
else
{
opnd2 = stack.pop();
if(stack.size()==0)
{
cout<<"This program cannot process unary operation";
exit(1);
}
opnd1 = stack.pop();
value = oper(c, opnd1, opnd2);
stack.push(value);
}
}
if(stack.size()>=2)
{
cout<<"Sory! this program cannot calculate this"<<endl;
cout<<"Enter +, *, /, - or ^ between bracket"<<endl;
exit(4);
}
return (stack.pop());
}
int main()
{
Convert convert;
Evaluate evaluate;
string bracketted_infix;
char infix[50], postfix[50];
char choice;
while(1)
{
cout<<"Enter operation: ";
cin>>infix;
cout<<endl;
cout<<"Entered operation: "<<infix<<endl;
bracketted_infix = convert.return_with_bracket(infix);
convert.to_Postfix(bracketted_infix, postfix);
cout<<"Equivalent Postfix operation: "<<postfix<<endl;
cout<<"RESULT: ";
cout<<evaluate.eval(postfix, convert);
cout<<"\nCalculate another operation?(y/n) ";
cin>>choice;
cout<<endl;
if(choice=='n')
break;
}
return 0;
}
To get it actually compiling you need to fix two syntax errors;
On line 154 you are calling a method with no parameter,
but the only declaration of this method takes 1 parameter.
if (this->isOperand) {
I believe you may have meant:
if (this->isOperand(c)) {
Also on line 255 you have a missing bracket before the semicolon:
double eval(char expr[], Convert &Wink;
When I actually ran your code it failed at runtime, with VS2010 giving an error "string subscript out of range".
If you're not already, I would recommend using a good IDE (such as Visual C++) when developing; the syntax colouring and support for dynamic debugging (i.e. breakpoints and watches) would be very helpful to debug a program like this.
Here is the final solution
#include<iostream>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<string>
#define MAX_SIZE 20
using namespace std;
template<class T>
class Stack
{
private:
T item[MAX_SIZE];
int top;
public:
Stack()
{
top = -1;
}
void push(T data)
{
if(!this->is_full())
item[++top] = data;
else
{
cout<<"Stack Error"<<endl;
exit(10);
}
}
T pop()
{
if(!this->is_empty())
return item[top--];
else
{
cout<<"Stack is Empty"<<endl;
exit(11);
}
}
int size()
{
return top+1;
}
bool is_empty()
{
if(top==-1)
return true;
else
return false;
}
bool is_full()
{
if(top==MAX_SIZE-1)
return true;
else
return false;
}
void display()
{
for(int i=0; i<this->size(); i++)
{
cout<<item[i]<<" ";
}
cout<<endl;
}
T return_top()
{
return item[top];
}
};
class Convert
{
private:
bool num_flag;
bool tow_digit_flag;
public:
Convert();
string return_with_bracket(string infix);
void to_Postfix(string infix,char postfix[]);
bool prcd(char op1, char op2);
int isOperand(char op);
int isOperator(char op);
bool return_flag()
{
return num_flag;
}
};
Convert::Convert()
{
this->num_flag = false;
this->tow_digit_flag = false;
}
string Convert::return_with_bracket(string infix)
{
return("(" + infix + ")");
}
bool Convert::prcd(char op1, char op2)
{
if((op1=='+' || op1=='-' || op1=='*' || op1=='/') && op2=='(' )
return true;
if(op1=='+' && op2=='+')
return true;
if(op1=='-' && op2=='-')
return false;
if(op1=='-' && op2=='+')
return false;
if(op1=='+' && op2=='-')
return false;
if(op1=='/' && op2=='/')
return false;
if(op1=='/' && (op2=='-' || op2=='+'))
return true;
if(op1=='*' && (op2=='+' || op2=='-'))
return true;
if((op1 == '-' || op1 == '+') && (op2 =='*' || op2 == '/'))
return false;
if((op1=='$' || op1 == '+') && (op2 =='*' || op2 == '/' || op2=='-'))
return true;
if((op1 == '-' || op1 == '+' || op1 =='*' || op1 == '/')&& op2=='^')
return false;
if(op1 == '^' && ( op2 == '+' || op2 =='*' || op2 == '/' || op2=='-'))
return false;
}
int Convert::isOperand(char op)
{
return(op>= '0' && op <= '9');
}
int Convert::isOperator(char op)
{
return(op=='+' || op=='-' || op == '/' || op=='*' || op=='^');
}
void Convert::to_Postfix(string infix, char postfix[])
{
int position, outpos=0;
char c;
int count = 0;
char temp;
char stacktop ;
Stack<char> stack;
for(position = 0; (c = infix[position])!='\0'; position++)
{
if (this->isOperand(c))
{
postfix[outpos++] = c;
this->num_flag = true;
count++;
if(count>=2)
{
this->tow_digit_flag = true;
}
}
else if(this->isOperator(c))
{
count = 0;
if(isOperator(infix[position]) && isOperator(infix[position+1]))
{
cout<<"\aMissing argument in between "<<infix[position]<<" and "<<infix[position+1]
<<" in column "<< position+1<<endl;
exit(9);
}
if(this->prcd(c, stacktop))
{
stacktop=stack.return_top();
stack.push(c);
stacktop = c;
}
else
{
while(true)
{
temp = stack.pop();
postfix[outpos++] =temp;
stacktop = stack.return_top();
if(prcd(c, stacktop) || stacktop=='(')
break;
}
stack.push(c);
stacktop = stack.return_top();
}
}
else if(c=='(')
{
count = 0;
stack.push(c);
stacktop = stack.return_top();
}
else if(c==')')
{
count = 0;
while(1)
{
if(stack.size()==0)
{
cout<<"Warning!! Number of ')' is greater than '('" <<endl;
exit(2);
}
temp = stack.pop();
if(temp!='(')
{
postfix[outpos++] = temp;
}
else
{
break;
}
}
stacktop =stack.return_top();
}
else
{
cout<<"Invalid input";
exit(3);
}
if(infix[position]==')' && infix[position+1]=='(')
{
stack.push('*');
stacktop = stack.return_top();
}
}
if(stack.size()!=0)
{
cout<<"Warning!!Number of '(' is greater than ')'"<<endl;
// exit(6);
}
if(!this->return_flag())
{
cout<<"You must Enter Numeric value for calculation"<<endl;
cout<<"This program cannot perform operations on variables";
exit(5);
}
if(this->tow_digit_flag)
{
cout<<"Sory! Althoug u may have entered right string"<<endl;
cout<<"this program is only for single digit operation"<<endl;
exit(8);
}
postfix[outpos] = '\0';
}
class Evaluate
{
public:
double eval(char expr[], Convert &Wink);
double oper(int symb, double op1, double op2);
};
double Evaluate::oper(int symb, double op1, double op2)
{
switch(symb)
{
case '+':
return (op1 + op2);
case '-':
return (op1 - op2);
case '*':
return (op1 * op2);
case '/':
return (op1 / op2);
case '^':
return (pow(op1, op2));
}
}
double Evaluate::eval(char expr[],Convert &convert)
{
int c, position;
char temp1;
int count = 0;
double opnd1, opnd2, value;
Stack<double> stack;
for(position = 0; (c = expr[position])!='\0'; position++)
{
if(convert.isOperand(c))
{
temp1 = char(c-'0');
stack.push(temp1);
}
else
{
opnd2 = stack.pop();
if(stack.size()==0)
{
cout<<"This program cannot process unary operation";
exit(1);
}
opnd1 = stack.pop();
value = oper(c, opnd1, opnd2);
stack.push(value);
}
}
if(stack.size()>=2)
{
cout<<"Sory! this program cannot calculate this"<<endl;
cout<<"Enter +, *, /, - or ^ between bracket"<<endl;
exit(4);
}
return (stack.pop());
}
int main()
{
Convert convert;
Evaluate evaluate;
string bracketted_infix;
char infix[50], postfix[50];
char choice;
while(1)
{
cout<<"Enter operation: ";
cin>>infix;
cout<<endl;
cout<<"Entered operation: "<<infix<<endl;
bracketted_infix = convert.return_with_bracket(infix);
convert.to_Postfix(bracketted_infix, postfix);
cout<<"Equivalent Postfix operation: "<<postfix<<endl;
cout<<"RESULT: ";
cout<<evaluate.eval(postfix, convert);
cout<<"\nCalculate another operation?(y/n) ";
cin>>choice;
cout<<endl;
if(choice=='n')
break;
}
return 0;
}