/// <summary> /// Will update text in input TextBox and set cursor on correct position /// </summary> /// <param name="str"></param> private void AddStringToEquation(string str) { string destination = MainEquationInputTextBox.Text; StringControl.InsertString(ref destination, str, ref _cursor); UpdateMainEquationInputTextBoxText(destination); }
/// <summary> /// fill multiply operators between: /// constant | number; /// number | constant; /// constant | constant; /// ) | constant, number, (; /// constant, number | (; /// constant, number, ) | function; /// (if there is no operator) /// </summary> /// <param name="equation">string containing equation</param> /// <returns>equation with filled multiply operators where are required</returns> private static string FixMissingMultiplyOperator(string equation) { for (int i = equation.Length - 1; i > 0; --i) { char ch1 = equation[i - 1]; char ch2 = equation[i]; // constant | number if ((StringControl.IsLastCharOfConstantConstant(ch1) && StringControl.GetConstantStringByLastChar(equation.Substring(0, i)) != string.Empty && StringControl.IsNumberChar(ch2)) // number | constant || (StringControl.IsNumberChar(ch1) && StringControl.IsFirstCharOfConstantConstant(ch2) && StringControl.GetConstantString(equation.Substring(i)) != string.Empty) // constant | constant || (StringControl.IsLastCharOfConstantConstant(ch1) && StringControl.GetConstantStringByLastChar(equation.Substring(0, i)) != string.Empty && StringControl.IsFirstCharOfConstantConstant(ch2) && StringControl.GetConstantString(equation.Substring(i)) != string.Empty) // ) | constant number ( || (ch1 == ')' && (StringControl.IsNumberChar(ch2) || StringControl.IsFirstCharOfConstantConstant(ch2) && StringControl.GetConstantString(equation.Substring(i)) != string.Empty || ch2 == '(')) // constant number | ( || ((StringControl.IsNumberChar(ch1) || StringControl.IsLastCharOfConstantConstant(ch1) && StringControl.GetConstantStringByLastChar(equation.Substring(0, i)) != string.Empty) && ch2 == '(') // constant number ) | function || ((StringControl.IsNumberChar(ch1) || StringControl.IsLastCharOfConstantConstant(ch1) && StringControl.GetConstantStringByLastChar(equation.Substring(0, i)) != string.Empty || ch1 == ')') && Operators.IsFirstCharOfFunctionOperator(ch2) && Operators.GetOperator(equation.Substring(i)) != OperatorsEnum.None) ) { equation = equation.Insert(i, Strings.Multiply); } } return(equation); }
/// <summary> /// </summary> /// <param name="equation">string containing equation</param> /// <returns>equation string with simplified operators</returns> private static string SimplifyOperatorsInsideEquation(string equation) { for (int i = 0; i < Operators.OperatorsToReplace.Length / 2; i += 1) { equation = StringControl.ReplaceAll(equation, Operators.OperatorsToReplace[i * 2], Operators.OperatorsToReplace[i * 2 + 1]); } return(equation); }
/// <summary> /// will delete char from MainEquationInputTextBox and set cursor /// </summary> /// <param name="sender">button</param> /// <param name="e">click event</param> private void DelButton_Click(object sender, RoutedEventArgs e) { if (_cursor > 0) { UpdateMainEquationInputTextBoxText( StringControl.RemoveCharFromString(MainEquationInputTextBox.Text, ref _cursor)); HandleChangeInEquation(); } }
/// <summary> /// will check equation if there are no unknown characters /// </summary> /// <param name="equation">string containing equation</param> /// <returns>true if equation does not contains unknown character else false if contains</returns> private bool CheckUnknownCharacter(string equation) { int i = 0; while (equation.Length > i) { // check if is constant -> the it is good :) if (StringControl.IsFirstCharOfConstantConstant(equation[i]) && StringControl.GetConstantString(equation.Substring(i)) != string.Empty) { i += StringControl.GetConstantString(equation.Substring(i)).Length; } else if (StringControl.IsNumberChar(equation[i])) { // get string of number characters string substring = string.Empty; do { substring += equation[i++]; }while (equation.Length > i && StringControl.IsNumberChar(equation[i])); // check if string can be converted to number try { StringToDouble(substring, ref _error); } catch { return(false); } } else { // get string of all another characters string substring = string.Empty; do { substring += equation[i++]; }while (equation.Length > i && !StringControl.IsNumberChar(equation[i]) && !(StringControl.IsFirstCharOfConstantConstant(equation[i]) && StringControl.GetConstantString(equation.Substring(i)) != string.Empty)); if (!CheckStringOfOperators(substring)) { _error = ErrorsEnum.InvalidSequenceOfCharacters; return(false); } } } return(true); }
/// <summary> /// calculate result, /// if there is error, print error instead of invalid result /// </summary> private void Calculate() { double?result = _calculator.Calculate(MainEquationInputTextBox.Text); ShowResult(result.HasValue ? StringControl.DoubleToString(result.Value) : _calculator.GetError()); if (result.HasValue) { ShowAns(); } }
/// <summary> /// </summary> /// <param name="equation">string containing equation</param> /// <param name="index">index of ending char of number or ending bracket</param> /// <returns>starting index of number or starting index of corresponding bracket to given bracket</returns> private int GetStartingIndexOfNumberOrStringInsideBracketOnIndex(string equation, int index) { int startingIndex = index; if (equation[index] == ')') { // if there is bracket on index, return index of starting bracket startingIndex = GetStartingBracketOfBracketOnIndex(equation, index); } else { // else check for staring index of number or constant while (startingIndex >= 0 && (StringControl.IsNumberChar(equation[startingIndex]) || StringControl.IsLastCharOfConstantConstant(equation[startingIndex]))) { if (StringControl.IsLastCharOfConstantConstant(equation[startingIndex])) { string constant = StringControl.GetConstantStringByLastChar(equation.Substring(0, startingIndex + 1)); if (constant == string.Empty) { break; } startingIndex -= constant.Length; } else { --startingIndex; } } ++startingIndex; } if (index < startingIndex) { // if there if no number/ constant/ bracket _error = ErrorsEnum.OperatorDoNotHaveEnoughArguments; throw new SyntaxErrorException(); } if (startingIndex == -1) { // shouldn't happened - fixed before solving tree _error = ErrorsEnum.UnknownError; throw new SyntaxErrorException(); } return(startingIndex); }
/// <summary> /// </summary> /// <param name="equation">string containing equation</param> /// <returns>equation without brackets but same size with number characters on place brackets and their content</returns> private string ReplaceBracketsAndTheirContentWithNumberCharacters(string equation) { while (equation.Contains('(')) { int startingIndex = equation.IndexOf('('); int endingIndex = GetEndingBracketOfBracketOnIndex(equation, startingIndex); int length = endingIndex - startingIndex + 1; string numberChars = StringControl.GenerateStringOfNumberCharacters(length); equation = equation.Remove(startingIndex, length).Insert(startingIndex, numberChars); } return(equation); }
/// <summary> /// Will add brackets if there are more unctions without brackets /// </summary> /// <param name="equation">string containing equation</param> /// <returns>equation</returns> private string FixFunctionInFunctionWithoutBracket(string equation) { string tmpEquation = equation; List <int> indexesForStartingBracket = new List <int>(); List <int> indexesForEndingBracket = new List <int>(); // search for last one argument operator int op; while ((op = GetLastIndexOfOperatorFromEnumArray(tmpEquation, Operators.OperatorsPriority1)) != -1) { int lengthOfOperator = Operators.GetOperatorFromEnum(Operators.GetOperator(tmpEquation.Substring(op))) .Length; // getting indexes for brackets indexesForStartingBracket.Add(op + lengthOfOperator); // ending bracket should be after number or after inner function // if there is internal function, then was replaced with number characters indexesForEndingBracket.Add( GetEndingIndexOfNumberOrStringInsideBracketOnIndex(tmpEquation, op + lengthOfOperator) + 1); // replace actual function with number chars tmpEquation = tmpEquation.Remove(op, lengthOfOperator).Insert(op, StringControl.GenerateStringOfNumberCharacters(lengthOfOperator)); } // sort indexes for adding brackets from the end DecreasingComparer decreasingComparer = new DecreasingComparer(); indexesForStartingBracket.Sort(decreasingComparer); indexesForEndingBracket.Sort(decreasingComparer); // adding brackets while (indexesForStartingBracket.Any() || indexesForEndingBracket.Any()) { if (!indexesForEndingBracket.Any() || indexesForStartingBracket.First() > indexesForEndingBracket.First()) { equation = equation.Insert(indexesForStartingBracket.First(), "("); indexesForStartingBracket.Remove(indexesForStartingBracket.First()); } else { equation = equation.Insert(indexesForEndingBracket.First(), ")"); indexesForEndingBracket.Remove(indexesForEndingBracket.First()); } } return(equation); }
/// <summary> /// Converts string tu number /// </summary> /// <param name="str">string containing number</param> /// <param name="error">reference to ErrorsEnum which is set before throwing errors</param> /// <returns>return number representing number in string or set error end throw exception if cant convert</returns> public double StringToDouble(string str, ref ErrorsEnum error) { // check if is constant switch (str) { case Strings.Pi: return(Math.PI); case Strings.Ans: return(_ansValue); case Strings.Memory: return(_memoryValue); } // return Convert.ToDouble(str); // or harder way :) (FloatSeparator can be changed to any char) double number = 0; double floatingPartOfNumber = 0; int index = 0; // convert integer part of number while (str.Length > index && str[index] != StringControl.FloatSeparator) { StringControl.CheckIfIsDigit(str[index], ref error); number *= 10; number += str[index++] - '0'; } // convert floating part of number if (str.Length > index && str[index] == StringControl.FloatSeparator) { index = str.Length - 1; while (str[index] != StringControl.FloatSeparator) { StringControl.CheckIfIsDigit(str[index], ref error); floatingPartOfNumber /= 10; floatingPartOfNumber += str[index--] - '0'; } floatingPartOfNumber /= 10; } return(number + floatingPartOfNumber); }
/// <summary> /// </summary> /// <param name="equation">string containing equation</param> /// <returns>returns number of missing ending brackets or -1 if invalid syntax</returns> private int CheckBrackets(string equation) { // check if there is empty bracket if (equation.Contains("()")) { _error = ErrorsEnum.EmptyBrackets; return(-1); } // creating string consist only of brackets string bracketsString = string.Empty; int i = 0; while (equation.Length > i) { while (equation.Length > i && (equation[i] == '(' || equation[i] == ')')) { bracketsString += equation[i++]; } ++i; } // deleting most internal brackets until there are no right ')' brackets // or there is invalid sequence of brackets while (bracketsString.Contains("()")) { bracketsString = StringControl.RemoveAll(bracketsString, "()"); } // counting missing brackets int missingBrackets = 0; foreach (char bracket in bracketsString) { if (bracket != '(') { // there is invalid sequence of brackets _error = ErrorsEnum.InvalidSequenceOfBrackets; return(-1); } ++missingBrackets; } return(missingBrackets); }
/// <summary> /// Will solve problem with minus before brackets and on another locations /// </summary> /// <param name="equation">string containing equation</param> /// <returns>equation</returns> private static string FixMinusOperator(string equation) { // get all locations of minus char in equation List <int> indexes = StringControl.GetAllIndexesOf(equation, Strings.Minus); // check all minuses (must be checking from the end because of adding to equation string on index) // add plus to equation if needed for (int index = indexes.Count - 1; index >= 0; --index) { if (indexes[index] > 0 && !Operators.IsLastCharOfTwoArgumentsOperator(equation[indexes[index] - 1])) { equation = equation.Insert(indexes[index], Strings.Plus); } } return(equation); }
/// <summary> /// Will move factorial operator before its argument for easier tree creating /// </summary> /// <param name="equation">string containing equation</param> /// <returns>equation</returns> private string MoveFactorialOperatorForCreatingTree(string equation) { List <int> indexes = StringControl.GetAllIndexesOf(equation, Strings.Factorial); //for (int index = indexes.Count - 1; index >= 0; --index) // equation = equation.Remove(indexes[index], Strings.Factorial.length) // .Insert(indexes[index], ")") // .Insert(GetStartingIndexOfNumberOrStringInsideBracketOnIndex(equation, indexes[index] - 1), "(" + Strings.Factorial); foreach (int index in indexes) { equation = equation.Remove(index, Strings.Factorial.Length); equation = equation.Insert(GetStartingIndexOfNumberOrStringInsideBracketOnIndex(equation, index - 1), Strings.Factorial); } return(equation); }
/// <summary> /// will simplify equation and add missing character /// </summary> /// <param name="equation">string containing equation</param> /// <returns>equation ready for creating tree</returns> private string PrepareEquationForProcessing(string equation) { //equation = equation.ToLower(); //equation = AddMissingBrackets(equation); //equation = SimplifyOperatorsInsideEquation(equation); //equation = MoveFactorialOperatorForCreatingTree(equation); //equation = FixFunctionInFunctionWithoutBracket(equation); //equation = FixMinusBeforeBracket(equation); //equation = FixMissingMultiplyOperator(equation); return(FixMissingMultiplyOperator( FixMinusOperator( FixFunctionInFunctionWithoutBracket( MoveFactorialOperatorForCreatingTree( SimplifyOperatorsInsideEquation( AddMissingBrackets( AddMissingBrackets( StringControl.RemoveSpaces( equation.ToLower()))))))))); }
/// <summary> /// </summary> /// <param name="equation">string containing equation</param> /// <param name="index">index of ending char of number or starting bracket</param> /// <returns>ending index of number or ending index of corresponding bracket to given bracket</returns> private int GetEndingIndexOfNumberOrStringInsideBracketOnIndex(string equation, int index) { int endingIndex = index; if (equation[index] == '(') { // if there is bracket on index, return index of starting bracket endingIndex = GetEndingBracketOfBracketOnIndex(equation, index); } else { // else check for staring index of number or constant while (endingIndex < equation.Length && (StringControl.IsNumberChar(equation[endingIndex]) || StringControl.IsConstantChar(equation[endingIndex]))) { ++endingIndex; } --endingIndex; } if (index > endingIndex) { // if there if no number/ constant/ bracket _error = ErrorsEnum.OperatorDoNotHaveEnoughArguments; throw new SyntaxErrorException(); } if (endingIndex == -1) { // shouldn't happened - fixed before solving tree _error = ErrorsEnum.UnknownError; throw new SyntaxErrorException(); } return(endingIndex); }
/// <summary> /// Will show text in memory TextBox /// </summary> private void ShowMemory() { MemoryTextBox.Text = StringControl.DoubleToString(_calculator.GetMemory()); }
/// <summary> /// Will show text in ans TextBox /// </summary> private void ShowAns() { AnsTextBox.Text = StringControl.DoubleToString(_calculator.GetAns()); }
/// <summary> /// Will add missing ending bracket /// </summary> /// <param name="equation">string containing equation</param> /// <returns>equation</returns> private string AddMissingBrackets(string equation) { int count = CheckBrackets(equation); return(count > 0 ? equation + StringControl.GenerateStringOfCharacters(count, ')') : equation); }