#include <iostream>
#include <cstring>
#include <cstdlib>
using namespace std;
/** Gets input from keyboard
*
* @return - char *expr
*/
char *input_expression()
{
cout << "Enter expression: ";
char *expr = new char[256];
cin.getline(expr, 256);
return expr;
}
/** Deletes element from array
*
* @param arr - array of any type
* @param size - size of array arr
* @param pos - index of element to delete
*/
template <class T>
void delete_element(T *arr, int &size, int pos)
{
for (int i = pos; i < size; i++)
arr[i]=arr[i+1];
--size;
}
/** Gets intermediate result and makes appropriate changes in expression
* which represented by array of numbers and array of operations.
*
* Example: 4 + 2 * 3 => numbers=(4, 2, 3), operations=(+, *)
* After applaying mid result: numbers=(4, 6), operations=(+,)
*
* @param operations - array of operations in expression
* @param numbers - array of numbers in expression
* @param op_counter - size of array operations
* @param num_counter - size of array num_counter
* @param i - index of changed elements
* @param mid_result - result of calculation of current operation
*/
void apply_mid_result(char *operations, double *numbers,
int op_counter, int num_counter,
int i, double mid_result)
{
delete_element(operations, op_counter, i);
delete_element(numbers, num_counter, i);
numbers[i] = mid_result;
}
/** Parses given expression as string to arrays of numbers and operations.
*
* @param expr - arithmetic expression, stored in array of char
* @param numbers - array of double, used as storage of all operands
* @param num_counter - size of array numbers
* @param operations - array of char, used as storage of all operations
* @param op_counter - size of array operations
*/
void parse_expression(char *expr, double *numbers, int &num_counter,
char *operations, int &op_counter)
{
char oper_signs[] = "*/+-";
double number;
char *pch = expr;
while (pch != NULL)
{
number = strtod(pch, &pch);
numbers[num_counter] = number;
++num_counter;
pch = strpbrk(pch, oper_signs);
if (pch != NULL)
{
operations[op_counter] = *pch;
++op_counter;
++pch;
}
}
}
/** Calculates according to priority of operations, returns result of calculation.
*
* NOTE: can calculate expressions without brackets and with standard
* arithmetic operations - addition, subtraction, multiplication, division.
*
* @param expr - arithmetic expression, stored in array of char
* @return double result
*/
double calculate(char *expr)
{
char operations[127];
int op_counter = 0;
double numbers[128];
int num_counter = 0;
parse_expression(expr, numbers, num_counter, operations, op_counter);
double result = 0, mid_result;
int i = 0;
// first - high priority operations
while (i < op_counter)
{
if (operations[i] == '*')
{
mid_result = numbers[i] * numbers[i+1];
apply_mid_result(operations, numbers, op_counter, num_counter, i, mid_result);
}
else if (operations[i] == '/')
{
mid_result = numbers[i] / numbers[i+1];
apply_mid_result(operations, numbers, op_counter, num_counter, i, mid_result);
}
else ++i;
}
// last - low priority operations
i = 0;
while (i < op_counter)
{
if (operations[i] == '+')
{
mid_result = numbers[i] + numbers[i+1];
apply_mid_result(operations, numbers, op_counter, num_counter, i, mid_result);
}
else if (operations[i] == '-')
{
mid_result = numbers[i] - numbers[i+1];
apply_mid_result(operations, numbers, op_counter, num_counter, i, mid_result);
}
else ++i;
}
return mid_result;
}
int main()
{
char *expr = input_expression();
cout << "\nExpression: " << expr;
double result = calculate(expr);
cout << "\nResult: " << result << "\n";
return 0;
}