How to perform the division and multiplication first?
So I'm trying to make an equation generator where I can control how many operators there are and the range of operands from 1-10, right now the code works but only for addition and subtraction how can I get a correct result when there are division and multiplication in the equation?
public static float Maths()
{
System.Random rand = new System.Random();
float answer = 0;
List<char> operators = new List<char>() { '+', '-', '/', '*' };
List<int> operatorsThis = new List<int>();
List<float> operands = new List<float>();
int operatorsCount = 1;
int operandsMin = 1;
int operandsMax = 10;
StringBuilder sb = new StringBuilder();
float f;
for (int i = 0; i < operatorsCount; i++)
{
f = rand.Next(operandsMin, operandsMax + 1);
operands.Add(f);
sb.Append(f.ToString() + " ");
int r = rand.Next(4);
char c = operators[r];
operatorsThis.Add(r);
sb.Append(c + " ");
}
f = rand.Next(operandsMin, operandsMax + 1);
operands.Add(f);
sb.Append(f.ToString() + " ");
Debug.Log(sb.ToString());
f = operands[0];
answer = f;
int iLast = 0;
for (int i = 0; i < operatorsThis.Count; i++)
{
if (operatorsThis[i] < 2)
{
iLast = i;
f = operands[i + 1];
if (operatorsThis[i] == 0)
{
answer += f;
}
else if (operatorsThis[i] == 1)
{
answer -= f;
}
}
else
{
if (operatorsThis[i] == 2)
{
f /= operands[i + 1];
}
else if (operatorsThis[i] == 3)
{
f *= operands[i + 1];
}
if (i == operatorsThis.Count - 1)
{
if (operatorsThis[iLast] == 0)
{
answer += f;
}
else if (operatorsThis[iLast] == 1)
{
answer -= f;
}
}
}
}
Debug.Log(answer);
return answer;
}
}
Answer by aldonaletto · Jul 02, 2017 at 03:52 AM
Solving expressions from text is a complex task, but in your case things get much easier, since you have operands and operators stored in separate arrays: just solve the higher priority operations in a first pass, then solve the next lower priority, and so on.
In the first pass, find the first higher priority operator, solve the operation and store the result in the second operand, then delete the first operand and the operator and continue looking for the next high priority operation.
Let's see an example:
[a]+[b]*[c]-[d]/[e]*[f]+[g]
This would be stored in your arrays as:
[+][*][-][/][*][+]
[a][b][c][d][e][f][g]
In the first pass, the first higher priority operation is [b]*[c]: solve the operation and store the result in [c], then delete [b] and the operator *, what results in the following arrays:
[+][ - ][/][*][+]
[a][b*c][d][e][f][g]
After solving and deleting the second higher priority operation, the arrays would be:
[+][ - ][ * ][+]
[a][b*c][d/e][f][g]
After the third and last higher priority operation, they would become:
[+][ - ][ + ]
[a][b*c][d/e*f][g]
Then a simple pass would solve only the lower order priority operations, giving the right result.
Answer by Bunny83 · Jul 02, 2017 at 07:07 AM
As aldonaletto said it's a quite complicated topic. There are several ways how you could solve it. Infix notation has another problem as it might require brackets in order to perform a certain computation. Post- or pre- fix notation doesn't require brackets but is a bit difficult to read for humans ^^.
For example:
(4+5)*3+7/8 // infix
4 5 + 3 * 7 8 / + // post fix
+ * + 4 5 3 / 7 8 // prefix
In post fix notation the operator comes "after" the operands. When grouping it should be more obvious:
(((4 5 +) 3 *) (7 8 /) +)
Prefix notation is basically the usual "function call notation", though it's the hardest to read:
(+ (* (+ 4 5) 3) (/ 7 8))
Add( Mult( Add( 4, 5 ), 3 ), Div( 7, 8 ) )
For a computer it's much easier to parse post or prefix notation as it doesn't have an "order of operations" as the order is given by the notation. Infix on the other hand requires brackets in order to allow arbitrary equations.
A lot expression parser often convert the infix notation into post fix and then actually compute the result. I created this expression parser which actually parses the infix notation in "reverse order". It first substitutes all "brackets" with a token that can later be resubstituted. It build an expression tree where the top node is the last operation you will perform. Have a look at this:
(+)
/ \
/ \
(*) \
/ \ (/)
(+) 3 / \
/ \ 7 8
4 5
So my parser would first replace the bracket (4+5) with a placeholder and then split the whole thing at the lowest operator (+). The resulting parts are then recursively parsed again until you get down to a single number. The parser also supports functions and constants which can easily be extended with your own functions. The great thing is that the expression is parsed into an expression tree and can have variables. The already parsed expression can then be used like a method.
That's the correct way to handle expressions of arbitrary level of complexity. I've once written an expression evaluator that called itself recursively in order to solve higher priority operations, and it worked fine for most cases - but failed in some more complex expressions where the priority swung wildly like a roller coaster. A careful parsing is the best solution for a bullet proof expression evaluator.
Your answer
![](https://koobas.hobune.stream/wayback/20220612125313im_/https://answers.unity.com/themes/thub/images/avi.jpg)
Follow this Question
Related Questions
How to use the results of a dice roll? 2 Answers
OnGUI will not show up? 1 Answer
My audio doesn't play, I'm through my options... 1 Answer
Need help with c# 1 Answer