I've written code that will take any basic math sum input as a string (for instance, 2*3+4/4
) and solve it. The way I achieve this is by splitting the string into sub-strings, with multiplication and division being done first (based on the regular order of operations). So in our example sum we would be left with 2*3
and 4/4
.
It then solves these sums and replaces the original sub-string with the answer : 2*3+4/4
would become 6+1
. The numbers left in the addition string are then added into an array. All elements in the array are then added.
The part of my code in question is the function that identifies if there are any multiplication or division operations left to do, and if so, performs them. I feel like this function is very long and cumbersome and needs to be shortened, hence why I'm posting it here on CodeReview.
void mathInterpreter::format()
{
BasicQuestion TempQuestion;
basic_ops *solver = new basic_ops();
//If we have multiplication or division in our sum then we should do this loop.
for (int i = 0; MultDevCount != 0; i++)
{
//get some information about the question we are on, and create a temp string.
op_positions temp;
temp = positions_d[i];
std::string temp_str;
double MyAnswer;
//if the operation that we are on in the for loop happens to be a multiply or divide, then lets do that.
if (temp.operation == MULTIPLY || temp.operation == DIVIDE)
{
if (operation_count == 1) /* ONLY ONE OPERATION */
{
temp_str = user_string;
}
else if (positions_d[i].operation_at == positions_d.front().operation_at) /* FIRST OPERATION IN SUM */
{
temp_str = get_sum(temp, 0, positions_d[i + 1].operation_at);
}
else if (positions_d[i].operation_at == positions_d.back().operation_at) /* LAST OPERATION IN SUM */
{
temp_str = get_sum(temp, positions_d[i - 1].operation_at, 0);
}
else /* THE OPERATION IS IN THE MIDDLE OF THE SUM */
{
temp_str = get_sum(positions_d[i], positions_d[i - 1].operation_at, positions_d[i + 1].operation_at);
if (positions_d[i - 1].operation == SUBTRACT) temp_str = SUBTRACT_SYM + temp_str;
}
//setup the return question properly and then send it to the solver.
TempQuestion = quest_from_tuple(get_nums(temp_str));
answer SumAns;
SumAns = solver->performCalc(TempQuestion);
MyAnswer = SumAns.answer;
if (SumAns.error)
{
error = true;
delete TempQuestion.numbers;
return;
}
//replace the original sum string with it's answer string.
user_string = replace_strings(std::to_string(MyAnswer), temp_str, user_string);
delete (TempQuestion.numbers);
//sort operation counts.
operation_count = CountOperations();
positions_d.clear();
populate_op_positions();
//an operation has been removed, so positions_d[i] may have changed. If positions_d[i] is still a mult or dev, we need to
//redo this loop with the same value for i. So subtract one so that the loop is redone with the same value.
if (positions_d[i].operation == MULTIPLY || positions_d[i].operation == DIVIDE) i--;
}
}
}
Some additional information: positions_d
is a deque which holds struct elements - the struct contains the position of an operation and what it is.
The get_sum()
function takes in a struct element (same struct as mentioned above) and the positions of the operations before and after it. It will then return a string with two operands and the operation (e.g. 2*3
).