-4

Title of topic might be confusing, but in example: we have equation like "3 / 4 * 4 + 4 / 3 / 2 - 4 / 4" so list contains values "3", "/", "4", "*", "4", "+", "4", "/", "3", "/", "2", "-", "4", "/", "4". I want process it into ( 3 / 4 * 4 ) + ( 4 / 3 / 2 ) - ( 4 / 4 ). It means equation values are grouped by rule of execution queue (* and / are always first in execution, before - and +)

  • Do you want your result to be a string with parentheses in the correct places, or a number that is the mathematical result of the parsed equation? – Teddy Ward Dec 08 '18 at 00:13
  • would the number 42 be in the list as "42" or as "4", "2"? Are *, /, +, and - the only valid operations? – Teddy Ward Dec 08 '18 at 00:14
  • 1
    one quick start would be to place a bracket at the start `(`, and one at the end `)` then do a replace of each `+` with `) + (` and so on for each of +,-,* etc – jazb Dec 08 '18 at 00:17
  • I did this in school waaaaaaaay back. You need to write a precedence parser. See if this link would be helpful: https://stackoverflow.com/questions/28256/equation-expression-parser-with-precedence – Jon Vote Dec 08 '18 at 00:22
  • Nope Teddy, "42" will be "42". *, /, + and - are the only valid operations. List also contains names of variables (I'm coding compilator), but I think it's not important here. JohnB gave nice solution, I can try it, but if u want to do ur solution Teddy, u are free to go. –  Dec 08 '18 at 00:28
  • Teddy, it will be string with parentheses in correct places. –  Dec 08 '18 at 00:51
  • @JohnB, depends if unnecessary `()`s are acceptable. What if you had `1*2+9-8+4/3`? `(1*2)+(9)-(8)+(4/3)` is probably not what you'd want. – ChiefTwoPencils Dec 08 '18 at 01:04

2 Answers2

1

An easy way out would be to use NCalc Library.

Expression e = new Expression("3 / 4 * 4 + 4 / 3 / 2 - 4 / 4");
e.Evaluate();
var equation = e.ParsedExpression.ToString();

Though that means the output would have more "(", ")", but Math Expression would be correct. Output of above would be

(((3 / 4) * 4) + ((4 / 3) / 2)) - (4 / 4)
Anu Viswan
  • 17,797
  • 2
  • 22
  • 51
  • Good answer, but more "(" give me harder to assembly equation : / –  Dec 08 '18 at 00:33
  • Then why do you need to add the parentheses at all? All of "3 / 4 * 4 + 4 / 3 / 2 - 4 / 4", "(3 / 4 * 4) + (4 / 3 / 2) - (4 / 4)" and "(((3 / 4) * 4) + ((4 / 3) / 2)) - (4 / 4)" are mathematically equivalent. Are you saying the only place you want to put parentheses is when switching from +,- to *,/ ? – Dylan Nicholson Dec 08 '18 at 01:25
  • (if so, `Regex.Replace(expr, "\d[ \d/*]+\d", "($1)")` should actually work, providing you don't need to support parentheses in the original expression) – Dylan Nicholson Dec 08 '18 at 01:32
  • I need it, because parentheses means the start of division/multiply sequence for loop. Regex.Replace is ok, but I want list of this values (not string). Anyway, I can test and use your regex on input equation declaration. –  Dec 08 '18 at 01:48
  • Sorry, yeah, make it @"\d[ \d/*]+\d" (or use \\d). Getting it as a list is simple if you know there are always spaces between numbers/symbols, otherwise you'll need a somewhat more sophisticated parser. – Dylan Nicholson Dec 08 '18 at 02:12
  • Regex changed in example "4 + 4 / 5 * 5 + 5 - 4 / 5" to "4 + ($1) + 5 - ($1)". I've got parser already, so if the regex would return proper value, all job would be done. –  Dec 08 '18 at 02:22
0

It can be done with regex, sure.

string s = "3/4*4 + 4 / 3/2+17-4/4";
string res = Regex.Replace(s, @"[^+-]*[*/][^+-]*", @"($0)");
Console.WriteLine(res); //(3/4*4 )+( 4 / 3/2)+17-(4/4)

I added some spaces for more fancy output, the regex looks for +-*/ only, so it does not care.

Antonín Lejsek
  • 6,003
  • 2
  • 16
  • 18