public static void SolutionManager(string formula, string usedVariable, bool closeAll, Dictionary <string, bool> methodsCheckDictionary) { // check if any methods were used if (Array.TrueForAll(methodsCheckDictionary.Values.ToArray(), (x) => (!x))) { ShowErrorMessageBox("Не выбраны способы решения", "Пожалуйста, отметьте хотя бы один способ решения"); return; } // if user wants unused windows to be closed if (closeAll) { foreach (var f in openedRootsWindows) { f.Close(); } } try { // convert to reverse polish notation string parsedFormula = FParser.MainParser(formula, usedVariable); // string formula -> function f(x) Func <double, double> parsedFunction = FuncConstructor.MainConstructor(parsedFormula, usedVariable); // dictionary with all methods Dictionary <string, Func <Func <double, double>, List <double> > > methodsFuncDictionary = new Dictionary <string, Func <Func <double, double>, List <double> > >() { { "Bisection (1)", Dichotomy.MainSolver }, { "Bisection (2)", SmallSegments.MainSolver }, { "Newton", Newton.MainSolver }, { "Chord", Chords.MainSolver }, { "Fixed Point", FixedPoint.MainSolver } //{"New method name", newClass.newSolver} }; // dictionary with lists of roots from all methods {"Method name", foundRootsList} Dictionary <string, List <double> > allRootsDictionary = new Dictionary <string, List <double> >(); // iterate over all used methods foreach (string methodName in methodsCheckDictionary.Keys) { // if method is not used if (!methodsCheckDictionary[methodName]) { continue; } List <double> foundRoots = methodsFuncDictionary[methodName](parsedFunction); foundRoots.Sort(); allRootsDictionary.Add(methodName, foundRoots); } // create and show window with roots output RootsOutput rootsOutput = new RootsOutput(formula, allRootsDictionary); openedRootsWindows.Add(rootsOutput); rootsOutput.Show(); } catch (Exception ex) { if (ex is WrongElementException || ex is NotEquationException || ex is SyntaxException || ex is TooManyRootsException) { ShowErrorMessageBox("Ошибка", ex.Message); } else { ShowErrorMessageBox("Ошибка", "Неизвестная ошибка\nПроверьте введённую формулу ещё раз или перезапустите программу"); } } }
public static string MainParser(string formula, string variable) { usedVariable = variable; formula = formula.ToLower(); formula = formula.Replace(" ", ""); if (!formula.Contains("=") || formula.EndsWith("=")) { // formula is not an equation throw new NotEquationException("Введите уравнение\nТакая запись некорректна, проверьте ещё раз"); } if (SymbolCount(formula, '(') != SymbolCount(formula, ')')) { //missing bracket throw new SyntaxException("Вы пропустили одну или несколько скобок\nТакая запись некорректна, проверьте ещё раз"); } if (usedVariable == "") { // no variable chosen throw new NotEquationException("Введите имя переменной, по которой будет решаться уравнение"); } if (!formula.Contains(usedVariable)) { // no variable in equation throw new NotEquationException("В выражении отстутсвует переменная, по которой будет решаться уравнение\nПроверьте введённую формулу ещё раз"); } // all terms to the left formula = formula.Replace("=", "-(") + ")"; // all formula to brackets (nothing is changed mathematically, but easier to process formula = "(" + formula + ")"; string[] ops = { "+", "-", "*", "/", "^", "(", ")" }; foreach (string op in ops) { // distinguish operators and brackets with whitespaces formula = formula.Replace(op, " " + op + " "); } // remove double whitespaces formula = formula.Replace(" ", " "); // remove whitespaces in the beginning and in the end formula = formula.Trim(); // change all unary minuses, so -3x becomes 0-3x formula = formula.Replace("( - ", "( 0 - "); // process cases like 45x or 6sin(y), when * is missing string[] pArr = { usedVariable, "sin", "cos", "tg", "ctg", "ln", "lg", "sqrt", "arcsin", "arccos", "arctg", "arcctg", "e", "pi" }; foreach (string p in pArr) { int displacement = 0; // pattern that matches such cases string prPattern = $@"([0-9]+){p}"; var matches = Regex.Matches(formula, prPattern); foreach (Match match in matches) { // only num part of match, like 45 from 45x string numMatch = match.Value.Replace(p, ""); // after replacement have 45 * x instead of 45x formula = formula.Substring(0, match.Index + displacement) + numMatch + " * " + p + formula.Substring(match.Index + displacement + match.Length); displacement += 3;// len("45x") + 3 = len("45 * x") } } FParser FP = new FParser(); return(FP.Compile(formula.Split(' '))); }