1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217
|
#include <string>
#include <stdlib.h>
#include <iostream>
#include <cstring>
#include <math.h>
#include <sstream>
using namespace std;
class Calculator {
/*
* This is calculator class to calculait equations given as a string.
* This class suports operations:
* +, -, *, /, (), sin(), cos(), tan(), sqrt()
* and can be easily extended.
* lines "for checking purposes" can be deleted or commented.
*/
public:
Calculator(string);
~Calculator();
void add_to_equation(string);
double count_equation();
int show_errors();
private:
//Variables
string equation;
int error_code;
int operation;
char right_parenthesis;
char left_parenthesis;
string key_actions;
string list_of_numbers;
string functions[4];
double PI;
//----------for checking purposes--------------------------//
string space;
//----------for checking purposes--------------------------//
//Functions
double count_element_in_equation(string);
double count_function(double, string);
int find_key_operation(string, bool);
double string_to_double(string);
string double_to_string(double);
string reverse_string(string);
int find_first_key_operation(size_t*, int);
bool check_key_action(string&, int&, size_t);
/*
* error_code:
* 101 - empty equation.
* 102 - wrong formula, missing bracket.
* 103 - wrong formula, several +, * and / found side by side.
* 104 - found the unknown function.
* */
};
Calculator::Calculator(string line = "") {
equation = line;
right_parenthesis = ')';
left_parenthesis = '(';
error_code = 0;
PI = 3.14159265;
key_actions = "*/+-";
list_of_numbers = "0123456789.";
functions[0] = "sqrt";
functions[1] = "sin";
functions[2] = "tan";
functions[3] = "cos";
//----------for checking purposes--------------------------//
space = " ";
//----------for checking purposes--------------------------//
}
Calculator::~Calculator() {}
void Calculator::add_to_equation(string line) {
//add equation to object or append it to equation in object.
equation += line;
}
double Calculator::count_equation() {
//----------for checking purposes--------------------------//
cout << "We calculate: " << equation << endl;
//----------for checking purposes--------------------------//
string string_temp;
double result = 0.0;
//checks whether variable equation are empty or have data in it.
//if empty sets error_code to 101 and returns result variable.
if (equation.empty()) {
error_code = 101;
return result;
}
//creats variables for right and left parenthesis locations in equation.
size_t found_right_parenthesis_location, found_left_parenthesis_location;
//search right paranthesis in equation.
found_right_parenthesis_location = equation.find(right_parenthesis);
//checks if right paranthesis was found or not.
if (found_right_parenthesis_location != string::npos) {
//if right paranthesis are found, then makes a copy of part of equation and reverse it
//to make it easy to find left paranthesis.
string_temp = reverse_string(equation.substr(0, found_right_parenthesis_location));
//search left paranthesis in equation.
found_left_parenthesis_location = string_temp.find(left_parenthesis);
//checks if left paranthesis was found or not.
if (found_left_parenthesis_location != string::npos) {
//if left paranthesis was found, then corrects location of left paranthesis in full equation.
found_left_parenthesis_location = string_temp.length() - found_left_parenthesis_location - 1;
}
else {
//if left paranthesis was not found, then sets error_code to 102 and returns result variable.
error_code = 102;
return result;
}
}
else {
//if right paranthesis are not found, then checks if left paranthesis are in equation.
found_left_parenthesis_location = equation.find(left_parenthesis);
if (found_left_parenthesis_location != string::npos) {
//if left paranthesis was not found, then sets error_code to 102 and returns result variable.
error_code = 102;
return result;
}
//if no paranthesis was found sets left paranthesis location to -1 and right paranthesis to string length.
//Because all equation are wraped in imaginary paranthesis.
found_left_parenthesis_location = -1;
found_right_parenthesis_location = equation.length();
}
string_temp = equation.substr(found_left_parenthesis_location + 1, found_right_parenthesis_location - found_left_parenthesis_location - 1);
//----------for checking purposes--------------------------//
cout << "I give: " << string_temp << endl;
//----------for checking purposes--------------------------//
//counts equation between left and right paranthesis.
result = count_element_in_equation(string_temp);
//----------for checking purposes--------------------------//
cout << "I got: " << result << endl;
//----------for checking purposes--------------------------//
//checks if paranthesis are from function or not.
if (found_left_parenthesis_location != string::npos) {
//if left paranthesis location are 0, here can't be anything in left of it.
if (found_left_parenthesis_location != 0) {
//if left paranthesis are not 0 checks that is in left of it.
//in left of left paranthesis can be another left paranthesis, one of key action or function.
//if it is function that function must be calculated.
char symbol;
bool found_symbol = false;
//gets a simbol in left of left paranthesis.
symbol = equation[found_left_parenthesis_location - 1];
//if simbol are left paranthesis skip all code in this if statment.
if (symbol != left_parenthesis) {
//checks if simbol are one of key actions.
for (int i = 0; i < 4; i++) {
if (symbol == key_actions[i]) {
found_symbol = true;
}
}
//if simbol are not one of key actions get functions name in left of left paranthesis.
if (!found_symbol) {
int location;
//gets location of first key action in left of left paranthesis.
location = find_key_operation(reverse_string(equation.substr(0, found_left_parenthesis_location)), true);
//changes location of left paranthesis, becouse function name was found.
found_left_parenthesis_location = found_left_parenthesis_location - location;
//calculates result of funcion.
result = count_function(result, equation.substr(found_left_parenthesis_location, location));
//----------for checking purposes--------------------------//
cout << "I calculated: " << equation.substr(found_left_parenthesis_location, location) << "()=" << result << endl;
//----------for checking purposes--------------------------//
}
}
}
}
if (found_left_parenthesis_location != string::npos) {
//if paranthesis was found, changes them to result of calculations.
equation.replace(found_left_parenthesis_location, found_right_parenthesis_location - found_left_parenthesis_location + 1, double_to_string(result));
//----------for checking purposes--------------------------//
cout << "I changed to: " << equation << endl << endl;
//----------for checking purposes--------------------------//
//calls function count_equation() to recalculate equation.
result = count_equation();
}
return result;
}
double Calculator::count_function(double number, string line) {
double result;
//checks which function need to be used and calculates given number.
if (line == functions[0])
result = sqrt(number);
else if (line == functions[1])
result = sin(number * PI / 180);
else if (line == functions[2])
result = tan(number * PI / 180);
else if (line == functions[3])
result = cos(number * PI / 180);
else {
//if function name are not found in functions[] gives back error code and returns 0.0.
error_code = 104;
result = 0.0;
}
return result;
}
|