|
|
|
|
@@ -44,89 +44,198 @@ void Calculator::run() {
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::string calculate(std::string equation) {
|
|
|
|
|
std::stringstream s(equation);
|
|
|
|
|
void Calculator::index(std::string equation, std::unordered_map<unsigned int, std::string>& nodes) {
|
|
|
|
|
unsigned int idx = 0;
|
|
|
|
|
|
|
|
|
|
//PEMDAS
|
|
|
|
|
while(equation.find('(') != std::string::npos) {
|
|
|
|
|
if(equation.find(')') == std::string::npos) {
|
|
|
|
|
return "error";
|
|
|
|
|
nodes.clear();
|
|
|
|
|
|
|
|
|
|
const static std::string operators[] = {
|
|
|
|
|
"(",
|
|
|
|
|
")",
|
|
|
|
|
"^",
|
|
|
|
|
"*",
|
|
|
|
|
"/",
|
|
|
|
|
"+",
|
|
|
|
|
"-"
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
for(const std::string& s : operators) {
|
|
|
|
|
|
|
|
|
|
while(equation.find(s, idx) != std::string::npos) {
|
|
|
|
|
int next = equation.find(s, idx);
|
|
|
|
|
nodes[next] = equation.substr(next, s.length());
|
|
|
|
|
idx = next + s.length();
|
|
|
|
|
}
|
|
|
|
|
idx = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int start = equation.find_last_of('(');
|
|
|
|
|
int end = equation.find_first_of(')', start);
|
|
|
|
|
|
|
|
|
|
std::string insert = calculate(equation.substr(start + 1, end - 1));
|
|
|
|
|
|
|
|
|
|
equation.replace(start, end, insert.c_str());
|
|
|
|
|
|
|
|
|
|
// -3+8*6-(8+4)^9/5
|
|
|
|
|
for(unsigned int i = 0; i < equation.length(); i++) {
|
|
|
|
|
static unsigned int begin = 0, end = 0;
|
|
|
|
|
if(nodes.find(i) == nodes.end()) {
|
|
|
|
|
if(nodes.find(i - 1) != nodes.end() || i == 0) {
|
|
|
|
|
//first digit of expression
|
|
|
|
|
begin = i;
|
|
|
|
|
}
|
|
|
|
|
if(nodes.find(i + 1) != nodes.end() || i == equation.length() - 1) {
|
|
|
|
|
//character after last digit of expression
|
|
|
|
|
end = i + 1;
|
|
|
|
|
nodes[begin] = equation.substr(begin, end - begin);
|
|
|
|
|
nodes[end - 1] = equation.substr(begin, end - begin);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
while(equation.find('^') != std::string::npos) {
|
|
|
|
|
int mid = equation.find('^');
|
|
|
|
|
int start = equation.rfind(' ', mid - 1);
|
|
|
|
|
int end = equation.find(' ', mid + 1);
|
|
|
|
|
double base = stod(equation.substr(start + 1, mid - 1));
|
|
|
|
|
double exp = stod(equation.substr(mid + 1, end - 1));
|
|
|
|
|
double Calculator::evaluate(std::string equation, std::unordered_map<char, std::string>& evalStr) {
|
|
|
|
|
|
|
|
|
|
std::string insert = std::to_string(pow(base, exp));
|
|
|
|
|
|
|
|
|
|
equation.replace(start, end, insert.c_str());
|
|
|
|
|
char op = '^';
|
|
|
|
|
|
|
|
|
|
while(equation.find(op) == std::string::npos) {
|
|
|
|
|
switch(op) {
|
|
|
|
|
case '^':
|
|
|
|
|
op = '*';
|
|
|
|
|
break;
|
|
|
|
|
case '*':
|
|
|
|
|
op = '/';
|
|
|
|
|
break;
|
|
|
|
|
case '/':
|
|
|
|
|
op = '+';
|
|
|
|
|
break;
|
|
|
|
|
case '+':
|
|
|
|
|
op = '-';
|
|
|
|
|
break;
|
|
|
|
|
case '-':
|
|
|
|
|
//no operator
|
|
|
|
|
if(evalStr.find(equation.front()) != evalStr.end()) {
|
|
|
|
|
return evaluate(evalStr[equation.front()], evalStr);
|
|
|
|
|
} else {
|
|
|
|
|
return std::stod(equation);
|
|
|
|
|
}
|
|
|
|
|
while(equation.find('*') != std::string::npos) {
|
|
|
|
|
int mid = equation.find('*');
|
|
|
|
|
int start = equation.rfind(' ', mid - 1);
|
|
|
|
|
int end = equation.find(' ', mid + 1);
|
|
|
|
|
double a = stod(equation.substr(start + 1, mid - 1));
|
|
|
|
|
double b = stod(equation.substr(mid + 1, end - 1));
|
|
|
|
|
|
|
|
|
|
std::string insert = std::to_string(a * b);
|
|
|
|
|
|
|
|
|
|
equation.replace(start, end, insert.c_str());
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
while(equation.find('/') != std::string::npos) {
|
|
|
|
|
int mid = equation.find('/');
|
|
|
|
|
int start = equation.rfind(' ', mid - 1);
|
|
|
|
|
int end = equation.find(' ', mid + 1);
|
|
|
|
|
double a = stod(equation.substr(start + 1, mid - 1));
|
|
|
|
|
double b = stod(equation.substr(mid + 1, end - 1));
|
|
|
|
|
|
|
|
|
|
std::string insert = std::to_string(a / b);
|
|
|
|
|
|
|
|
|
|
equation.replace(start, end, insert.c_str());
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
while(equation.find('+') != std::string::npos) {
|
|
|
|
|
int mid = equation.find('+');
|
|
|
|
|
int start = equation.rfind(' ', mid - 1);
|
|
|
|
|
int end = equation.find(' ', mid + 1);
|
|
|
|
|
double a = stod(equation.substr(start + 1, mid - 1));
|
|
|
|
|
double b = stod(equation.substr(mid + 1, end - 1));
|
|
|
|
|
|
|
|
|
|
std::string insert = std::to_string(a + b);
|
|
|
|
|
|
|
|
|
|
equation.replace(start, end, insert.c_str());
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
while(equation.find('-') != std::string::npos) {
|
|
|
|
|
int mid = equation.find('-');
|
|
|
|
|
int start = equation.rfind(' ', mid - 1);
|
|
|
|
|
if(start == std::string::npos) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
int end = equation.find(' ', mid + 1);
|
|
|
|
|
double a = stod(equation.substr(start + 1, mid - 1));
|
|
|
|
|
double b = stod(equation.substr(mid + 1, end - 1));
|
|
|
|
|
|
|
|
|
|
std::string insert = std::to_string(a - b);
|
|
|
|
|
|
|
|
|
|
equation.replace(start, end, insert.c_str());
|
|
|
|
|
}
|
|
|
|
|
//op is now the appropriate operator
|
|
|
|
|
|
|
|
|
|
//if either term is a placeholder, evaluate and substitute.
|
|
|
|
|
double a, b;
|
|
|
|
|
if(evalStr.find(equation.front()) != evalStr.end()) {
|
|
|
|
|
a = evaluate(evalStr[equation.front()], evalStr);
|
|
|
|
|
} else {
|
|
|
|
|
if(equation.find(op) == 0 && op == '-') {
|
|
|
|
|
a = 0;
|
|
|
|
|
} else {
|
|
|
|
|
a = std::stod(equation.substr(0, equation.find(op)));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return equation;
|
|
|
|
|
if(evalStr.find(equation.back()) != evalStr.end()) {
|
|
|
|
|
b = evaluate(evalStr[equation.back()], evalStr);
|
|
|
|
|
} else {
|
|
|
|
|
b = std::stod(equation.substr(equation.find(op) + 1));
|
|
|
|
|
}
|
|
|
|
|
switch(op) {
|
|
|
|
|
case '^':
|
|
|
|
|
return pow(a, b);
|
|
|
|
|
case '*':
|
|
|
|
|
return a * b;
|
|
|
|
|
case '/':
|
|
|
|
|
return a / b;
|
|
|
|
|
case '+':
|
|
|
|
|
return a + b;
|
|
|
|
|
case '-':
|
|
|
|
|
return a - b;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::string Calculator::calculate(std::string equation) {
|
|
|
|
|
|
|
|
|
|
//PEMDAS
|
|
|
|
|
while(equation.find(' ') != std::string::npos) {
|
|
|
|
|
equation.erase(equation.find(' '), 1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::unordered_map<unsigned int, std::string> nodes;
|
|
|
|
|
std::unordered_map<char, std::string> evalStr;
|
|
|
|
|
std::string eval = "a";
|
|
|
|
|
|
|
|
|
|
unsigned int idx = 0;
|
|
|
|
|
|
|
|
|
|
index(equation, nodes);
|
|
|
|
|
|
|
|
|
|
idx = 0;
|
|
|
|
|
|
|
|
|
|
// ()
|
|
|
|
|
while(equation.find(')', idx) != std::string::npos) {
|
|
|
|
|
int end = equation.find(')');
|
|
|
|
|
int begin = equation.rfind('(', end);
|
|
|
|
|
evalStr[eval.front()] = calculate(equation.substr(begin + 1, (end - begin) - 1));
|
|
|
|
|
equation.replace(begin, (end - begin) + 1, eval);
|
|
|
|
|
eval.front()++;
|
|
|
|
|
idx = end + 1;
|
|
|
|
|
}
|
|
|
|
|
idx = 0;
|
|
|
|
|
index(equation, nodes);
|
|
|
|
|
// ^
|
|
|
|
|
while(equation.find('^', idx) != std::string::npos) {
|
|
|
|
|
int mid = equation.find('^');
|
|
|
|
|
int begin = equation.find(nodes[mid - 1] + nodes[mid]);
|
|
|
|
|
int end = equation.find(nodes[mid] + nodes[mid + 1], begin) + (nodes[mid] + nodes[mid + 1]).length();
|
|
|
|
|
evalStr[eval.front()] = equation.substr(begin, end - begin);
|
|
|
|
|
equation.replace(begin, end - begin, eval);
|
|
|
|
|
eval.front()++;
|
|
|
|
|
idx = end + 1;
|
|
|
|
|
}
|
|
|
|
|
idx = 0;
|
|
|
|
|
index(equation, nodes);
|
|
|
|
|
// * or /
|
|
|
|
|
while(equation.find('*', idx) != std::string::npos || equation.find('/', idx) != std::string::npos) {
|
|
|
|
|
if(equation.find('*', idx) < equation.find('/', idx) && equation.find('*', idx) != std::string::npos) {
|
|
|
|
|
int mid = equation.find('*');
|
|
|
|
|
int begin = equation.find(nodes[mid - 1] + nodes[mid]);
|
|
|
|
|
int end = equation.find(nodes[mid] + nodes[mid + 1], begin) + (nodes[mid] + nodes[mid + 1]).length();
|
|
|
|
|
evalStr[eval.front()] = equation.substr(begin, end - begin);
|
|
|
|
|
equation.replace(begin, end - begin, eval);
|
|
|
|
|
eval.front()++;
|
|
|
|
|
idx = end + 1;
|
|
|
|
|
} else if(equation.find('/', idx) != std::string::npos) {
|
|
|
|
|
int mid = equation.find('/');
|
|
|
|
|
int begin = equation.find(nodes[mid - 1] + nodes[mid]);
|
|
|
|
|
int end = equation.find(nodes[mid] + nodes[mid + 1], begin) + (nodes[mid] + nodes[mid + 1]).length();
|
|
|
|
|
evalStr[eval.front()] = equation.substr(begin, end - begin);
|
|
|
|
|
equation.replace(begin, end - begin, eval);
|
|
|
|
|
eval.front()++;
|
|
|
|
|
idx = end + 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
idx = 0;
|
|
|
|
|
index(equation, nodes);
|
|
|
|
|
// + or -
|
|
|
|
|
while(equation.find('+', idx) != std::string::npos || equation.find('-', idx) != std::string::npos) {
|
|
|
|
|
if(equation.find('+', idx) < equation.find('-', idx) && equation.find('+', idx) != std::string::npos) {
|
|
|
|
|
int mid = equation.find('+');
|
|
|
|
|
int begin = equation.find(nodes[mid - 1] + nodes[mid]);
|
|
|
|
|
int end = equation.find(nodes[mid] + nodes[mid + 1], begin) + (nodes[mid] + nodes[mid + 1]).length();
|
|
|
|
|
evalStr[eval.front()] = equation.substr(begin, end - begin);
|
|
|
|
|
equation.replace(begin, end - begin, eval);
|
|
|
|
|
eval.front()++;
|
|
|
|
|
idx = end + 1;
|
|
|
|
|
} else if(equation.find('-', idx) != std::string::npos) {
|
|
|
|
|
int mid = equation.find('-');
|
|
|
|
|
int begin = mid;
|
|
|
|
|
if(nodes.find(mid - 1) != nodes.end()) {
|
|
|
|
|
begin = equation.find(nodes[mid - 1] + nodes[mid]);
|
|
|
|
|
}
|
|
|
|
|
int end = equation.find(nodes[mid] + nodes[mid + 1], begin) + (nodes[mid] + nodes[mid + 1]).length();
|
|
|
|
|
evalStr[eval.front()] = equation.substr(begin, end - begin);
|
|
|
|
|
equation.replace(begin, end - begin, eval);
|
|
|
|
|
eval.front()++;
|
|
|
|
|
idx = end + 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return std::to_string(evaluate(equation, evalStr));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@@ -145,8 +254,9 @@ void Calculator::basicCalculator() {
|
|
|
|
|
ImGui::BeginGroup();
|
|
|
|
|
{
|
|
|
|
|
if(ImGui::Button("AC")) {
|
|
|
|
|
s += " + ";
|
|
|
|
|
s.clear();
|
|
|
|
|
}
|
|
|
|
|
ImGui::SameLine();
|
|
|
|
|
if(ImGui::Button("()")) {
|
|
|
|
|
|
|
|
|
|
if(parenthesis) {
|
|
|
|
|
@@ -157,9 +267,11 @@ void Calculator::basicCalculator() {
|
|
|
|
|
|
|
|
|
|
parenthesis = !parenthesis;
|
|
|
|
|
}
|
|
|
|
|
ImGui::SameLine();
|
|
|
|
|
if(ImGui::Button("Gr")) {
|
|
|
|
|
graphing = true;
|
|
|
|
|
}
|
|
|
|
|
ImGui::SameLine();
|
|
|
|
|
if(ImGui::Button("=")) {
|
|
|
|
|
s = calculate(s);
|
|
|
|
|
}
|
|
|
|
|
@@ -190,6 +302,7 @@ void Calculator::basicCalculator() {
|
|
|
|
|
}
|
|
|
|
|
ImGui::SameLine();
|
|
|
|
|
if(ImGui::Button("del")) {
|
|
|
|
|
if(!s.empty()) {
|
|
|
|
|
if(s.back() == ' ') {
|
|
|
|
|
s.pop_back();
|
|
|
|
|
if(s.back() == '(' || s.back() == ')') {
|
|
|
|
|
@@ -202,6 +315,7 @@ void Calculator::basicCalculator() {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
ImGui::EndGroup();
|
|
|
|
|
|
|
|
|
|
ImGui::SameLine();
|
|
|
|
|
|