I am relatively new to C++ coming form languages such as Java and would like tips to make my code more C++ like and doing things in the C++ way.
The header file
#pragma once
#include <string>
#include <memory>
class Expression
{
public:
std::string symbol;
std::shared_ptr<Expression> left;
std::shared_ptr<Expression> right;
float eval();
static Expression parse(std::string s);
private:
Expression(std::string symbol, Expression *left, Expression *right);
static Expression parseRec(std::string s);
static float evalRec(const Expression &e);
};
cpp file:
#include "Expression.hpp"
#include <unordered_map>
Expression::Expression(std::string symbol, Expression *left, Expression *right)
: symbol(symbol), left(left), right(right) {}
float Expression::eval()
{
return Expression::evalRec(*this);
}
float Expression::evalRec(const Expression &e)
{
switch (e.symbol[0])
{
case '+':
return evalRec(*e.left) + evalRec(*e.right);
case '-':
return evalRec(*e.left) - evalRec(*e.right);
case '*':
return evalRec(*e.left) * evalRec(*e.right);
case '/':
return evalRec(*e.left) / evalRec(*e.right);
default:
return std::stoi(e.symbol);
}
}
Expression Expression::parse(std::string s)
{
//Remove whitespace
std::string output;
for (auto &i : s)
{
if (i != ' ')
output += i;
}
return parseRec(output);
}
Expression Expression::parseRec(std::string s)
{
const std::unordered_map<char, int> precedence = {{'+', 1}, {'-', 1}, {'*', 10}, {'/', 10}};
int indexOfLowest = -1;
int i = 0;
for (auto &&j : s)
{
switch (j)
{
case '+':
case '-':
case '*':
case '/':
if (indexOfLowest == -1)
indexOfLowest = i;
else if (precedence.at(j) <= precedence.at(s[indexOfLowest]))
indexOfLowest = i;
break;
default:
break;
}
i++;
}
if (indexOfLowest == -1)
{
return Expression(s, NULL, NULL);
}
else
{
return Expression(std::string(1, s[indexOfLowest]),
new Expression(parseRec(s.substr(0, indexOfLowest))),
new Expression(parseRec(s.substr(indexOfLowest + 1, s.length() - indexOfLowest - 1))));
}
}
and a simple main:
#include <iostream>
#include "Expression.hpp"
int main(int argc, char const *argv[])
{
//Parsed expression tree
Expression e = Expression::parse("5 + 10 * 2 + 6 / 3");
std::cout << e.eval() << std::endl;
return 0;
}
Many thanks