#include <math.
h>
#include <iostream>
#include <sstream>
#include <string>
#include <iomanip>
#include <queue>
#include <vector>
#include <stdlib.h>
#include <fstream>
#include <algorithm>
#include <map>
#include <stack>
#include <limits>
using namespace std;
class classOperator
public:
classOperator(char&,int&);
void addOperands(long double&, long double&);
bool operator < (const classOperator& str) const;
int value;
char actualclassOperator;
long double* pointer_To_leftOperand;
long double* pointer_To_rightOperand;
};
classOperator::classOperator(char &receivedclassOperator, int &receivedValue)
actualclassOperator = receivedclassOperator;
value = receivedValue;
void classOperator::addOperands(long double &receivedleft, long double &receivedright)
pointer_To_leftOperand=&receivedleft;
pointer_To_rightOperand=&receivedright;
bool classOperator::operator < (const classOperator& str) const
return (value < str.value);
inline void printOperatorVector(std::vector<classOperator> VectorToPrint)
for(unsigned int index = 0; index < VectorToPrint.size(); index++)
class Parenthesis
public:
Parenthesis(unsigned int,char);
char typeOfParenthesis;
unsigned int position;
private:
};
Parenthesis::Parenthesis(unsigned int receivedPosition, char parenthesisType)
position = receivedPosition;
typeOfParenthesis = parenthesisType;
class Expression
public:
Expression(std::string,bool);
double result;
private:
bool hasBrackets;
std::vector <Expression> subExpressions;
std::vector<Parenthesis> vector_parentheses; //If the position of a parenthesis in a vector
//is 'n', then the position of the closing parenthesis should be vectorSize-n in the
//same vector
void containsBrackets();//Checks to see if the expression contains parentheses
void getParentheses(); //Gets position and types of parentheses in the expression
void getSubExpressions(); //Gets the contents between each parenthesis so that they may be
evaluated
long double evaluate();
std::string expressionString;
};
Expression::Expression(std::string expression, bool sub) //NOTE: being a sub means that it was
surrounded
//by brackets '(' ')'
hasBrackets = false;
expressionString = expression;
containsBrackets();
if (hasBrackets == true)
getParentheses();
getSubExpressions();
evaluate();
long double Expression::evaluate()
{
std::map<char, unsigned int> classOperatorMap;
classOperatorMap['*']=2;
classOperatorMap['/']=2;
classOperatorMap['+']=1;
classOperatorMap['-']=1;
classOperatorMap['^']=2;
classOperatorMap['=']=1;
classOperatorMap['s']=1;
classOperatorMap['i']=1;
classOperatorMap['n']=1;
std::vector<long double> numbers;
std::vector<classOperator> classOperators;
long double number = 0;
std::string numberString = ""; //For having multi-digit numbers;
std::string numberStringBin = "";
int flag = 0;
for(unsigned int index = 0; index<=expressionString.size(); index++)
if(expressionString[index] != '+' && expressionString[index] != '-' && expressionString[index] != '*' &&
expressionString[index] != '/' && expressionString[index] != ' ' && expressionString[index] != '^' &&
expressionString[index] != '=')
if(expressionString[index] == 'b')
numberString+= expressionString[index];
flag = 1;
else if(expressionString[index] == 'f')
{
numberString+= expressionString[index];
flag = 2;
else if(expressionString[index] == 'p' && expressionString[index+1] == 'i')
numberString+= expressionString[index];
flag = 3;
else if(expressionString[index] == 'r' && expressionString[index+1] == 'a' &&
expressionString[index+2] == 'd' && expressionString[index+3] == 'i' && expressionString[index+4] == 'u'
&& expressionString[index+5] == 's')
numberString+= expressionString[index];
flag = 4;
else
numberString+= expressionString[index];
if (expressionString.size() == index)
{
if(flag == 1)
number=std::stoi(numberString, nullptr, 2);
numbers.push_back(number);
numberString="";
if(flag == 2)
number=std::stoi(numberString, nullptr, 16);
numbers.push_back(number);
numberString = "";
if(flag == 3)
number = 3.14;
numbers.push_back(number);
numberString = "";
if(flag == 4)
number = 3;
numbers.push_back(number);
numberString = "";
else
number= strtod(numberString.c_str(), NULL);
numbers.push_back(number);
numberString = "";
if(expressionString[index] == '+' || expressionString[index] == '-' || expressionString[index] == '*' ||
expressionString[index] == '/' || expressionString[index] == ' '|| expressionString[index] == '^' ||
expressionString[index] == '=')
number= strtod(numberString.c_str(), NULL);
numbers.push_back(number);
numberString = "";
for(unsigned int index = 0; index<expressionString.size(); index++)
if(expressionString[index] == '+' || expressionString[index] == '-' || expressionString[index] == '*' ||
expressionString[index] == '/' || expressionString[index] == ' '|| expressionString[index] == '^'||
expressionString[index] == '=')
int value = classOperatorMap[expressionString[index]];
if(numbers.size() > 2)
{
classOperator tempclassOperator(expressionString[index],value);
classOperators.push_back(tempclassOperator);
else
classOperator tempclassOperator(expressionString[index],value);
classOperators.push_back(tempclassOperator);
for(unsigned int index = 0; index < classOperators.size(); index++)
if(numbers.size() >= 2)
classOperators[index].addOperands(numbers[index],numbers[index+1]);
else
classOperators[index].addOperands(numbers[0],numbers[1]);
std::sort(classOperators.begin(),classOperators.end());
for(unsigned int index = 0; index < numbers.size(); index++)
}
printOperatorVector(classOperators);
std::stack<long double> numberStack;
std::stack<classOperator> classOperatorStack;
for (unsigned int index = 0; index < classOperators.size(); index++)
classOperatorStack.push(classOperators[index]);
long double Result = 0;
for(unsigned int index = classOperatorStack.size();index>0;index--)
unsigned int previousValue = classOperatorMap[classOperatorStack.top().actualclassOperator];
if (classOperatorStack.top().actualclassOperator == '*')
//change stack to vector
Result = *classOperatorStack.top().pointer_To_leftOperand*
*classOperatorStack.top().pointer_To_rightOperand;
numberStack.push(Result);
if(classOperatorStack.empty() == false)
classOperatorStack.pop();
else if (classOperatorStack.top().actualclassOperator == '/')
{
Result = *classOperatorStack.top().pointer_To_leftOperand/
*classOperatorStack.top().pointer_To_rightOperand;
numberStack.push(Result);
if(classOperatorStack.empty() == false)
classOperatorStack.pop();
else if (classOperatorStack.top().actualclassOperator == '+')
Result = *classOperatorStack.top().pointer_To_leftOperand+
*classOperatorStack.top().pointer_To_rightOperand;
numberStack.push(Result);
if(classOperatorStack.empty() == false)
classOperatorStack.pop();
else if (classOperatorStack.top().actualclassOperator == '-')
Result = *classOperatorStack.top().pointer_To_leftOperand-
*classOperatorStack.top().pointer_To_rightOperand;
numberStack.push(Result);
if(classOperatorStack.empty() == false)
classOperatorStack.pop();
}
else if (classOperatorStack.top().actualclassOperator == '^')
Result = pow(*classOperatorStack.top().pointer_To_leftOperand,
*classOperatorStack.top().pointer_To_rightOperand);
numberStack.push(Result);
if(classOperatorStack.empty() == false)
classOperatorStack.pop();
else if (classOperatorStack.top().actualclassOperator == '=')
Result = *classOperatorStack.top().pointer_To_rightOperand;
numberStack.push(Result);
if(classOperatorStack.empty() == false)
classOperatorStack.pop();
if(!classOperatorStack.empty())
if(classOperatorMap[classOperatorStack.top().actualclassOperator] > previousValue)
classOperatorStack.top().pointer_To_leftOperand = &Result;
if(classOperatorMap[classOperatorStack.top().actualclassOperator] <= previousValue)
classOperatorStack.top().pointer_To_rightOperand = &Result;
}
}
result = numberStack.top();
return 0;
void Expression::containsBrackets()
for(unsigned int index = 0; index < expressionString.size(); index++)
if (expressionString[index]=='(' ||expressionString[index]==')' )
hasBrackets = true;
void Expression::getParentheses() //Finds the parentheses and their positions in the expression
//so that their contents can be converted to sub expressions.
for (unsigned int index = 0; index < expressionString.size(); index++)
if (expressionString[index] == '(' || expressionString[index] == ')')
Parenthesis temporary(index, expressionString[index]); //Stores the position and type of the
parenthesis
vector_parentheses.push_back(temporary);
}
void Expression::getSubExpressions()
for(unsigned int index = 0; index < vector_parentheses.size(); index++)
if(vector_parentheses[index].typeOfParenthesis == '(')
std::string subExpression = "";
// | ( | ( | ( | ) | ) | ) |
// * - - - - *
// n=0 =size-n
//in an array of parentheses, corresponding closing parenthesis for an opening bracket at position
in is
// at [size-n]
unsigned int positionOfOpeningParenthesis = vector_parentheses[index].position;
unsigned int positionOfClosingParenthesis = vector_parentheses[vector_parentheses.size()-1 -
index].position;
for(unsigned int index2 = positionOfOpeningParenthesis+1; index2 <
positionOfClosingParenthesis;index2++)
subExpression+=expressionString[index2]; //gets stuff found between each bracket
Expression temporaryExpression(subExpression, true); //creates a new sub expression
int digits_before = 1 + (int)floor(log10(fabs(temporaryExpression.result)));
int digits_after = std::numeric_limits<long double>::digits10 - digits_before;
long double whole = floor(pow(10, digits_after) * fabs(temporaryExpression.result) + 0.5);
while (digits_after > 0 && (whole/10.0 - floor(whole/10.0)) < 0.05)
--digits_after;
whole = floor(whole / 10.0 + 0.5);
if (digits_after < 0) digits_after = 0;
std::stringstream ss;
ss << std::fixed << std::setprecision(digits_after) << temporaryExpression.result;
std::string stringResult = ss.str();
if(expressionString.size() <= positionOfOpeningParenthesis)
for (unsigned int index = expressionString.size(); index <=
positionOfOpeningParenthesis+stringResult.size();index++)
expressionString+=' ';
else
expressionString.replace(positionOfOpeningParenthesis,positionOfClosingParenthesis-
positionOfOpeningParenthesis +1,stringResult);
}
}
evaluate(); //Evaluates new expression containing the result of the sub expression
int main() {
std::cout << "**Tasks** " << std::endl;
std::cout << "Check equal bracket numbers" << std::endl;
std::cout << "Input support for negative input numbers" << std::endl;
std::cout << "Please enter file path of expression: " ;
ifstream file;
std::string path;
//cin>>path;
std::getline (std::cin, path);
file.open(path.c_str());
if(!file.is_open())
cout<<"Unable to open the file."<<endl;
return 0;
string line;
std::string expression;
while(getline(file, expression))
if(expression == "Quit")
break;
Expression expressionToEvaluate(expression, false);
std::cout << "Here is the output: " << std::fixed << setprecision(2)<<
expressionToEvaluate.result<< std::endl;
file.close();
return 0;