private BigInteger Solve() { if (_result == null) { _result = InfixNotation.Evaluate(Equation); //_result = StaticScriptControl.Evaluate(Equation); } return((BigInteger)_result); }
private decimal Solve() { if (_result == null) { _result = InfixNotation.Evaluate(Equation); //_result = StaticScriptControl.Evaluate(Equation); } return((decimal)_result); }
public static string Convert(string infixNotationString) { if (string.IsNullOrWhiteSpace(infixNotationString)) { throw new ArgumentException("Argument infixNotationString must not be null, empty or whitespace.", "infixNotationString"); } List <char> output = new List <char>(); Stack <char> operatorStack = new Stack <char>(); string sanitizedString = new string(infixNotationString.Where(c => AllowedCharacters.Contains(c)).ToArray()); string number = string.Empty; List <string> enumerableInfixTokens = new List <string>(); foreach (char c in sanitizedString) { if (InfixNotation.Operators.Contains(c) || "()".Contains(c)) { if (number.Length > 0) { enumerableInfixTokens.Add(number); number = string.Empty; } enumerableInfixTokens.Add(c.ToString()); } else if (InfixNotation.Numbers.Contains(c)) { number += c.ToString(); } else { throw new Exception(string.Format("Unexpected character '{0}'.", c)); } } if (number.Length > 0) { enumerableInfixTokens.Add(number); number = string.Empty; } foreach (string token in enumerableInfixTokens) { if (InfixNotation.IsNumeric(token)) { AddToOutput(output, token.ToArray()); } else if (token.Length == 1) { char c = token[0]; if (InfixNotation.Numbers.Contains(c)) { AddToOutput(output, c); } else if (InfixNotation.Operators.Contains(c)) { if (operatorStack.Count > 0) { char o = operatorStack.Peek(); if ((AssociativityDictionary[c] == Associativity.Left && PrecedenceDictionary[c] <= PrecedenceDictionary[o]) || (AssociativityDictionary[c] == Associativity.Right && PrecedenceDictionary[c] < PrecedenceDictionary[o])) { AddToOutput(output, operatorStack.Pop()); } } operatorStack.Push(c); } else if (c == '(') { operatorStack.Push(c); } else if (c == ')') { bool leftParenthesisFound = false; while (operatorStack.Count > 0) { char o = operatorStack.Peek(); if (o != '(') { AddToOutput(output, operatorStack.Pop()); } else { operatorStack.Pop(); leftParenthesisFound = true; break; } } if (!leftParenthesisFound) { throw new FormatException("The algebraic string contains mismatched parentheses (missing a left parenthesis)."); } } else { throw new Exception(string.Format("Unrecognized character '{0}'.", c)); } } else { throw new Exception(string.Format("String '{0}' is not numeric and has a length greater than 1.", token)); } } // foreach while (operatorStack.Count > 0) { char o = operatorStack.Pop(); if (o == '(') { throw new FormatException("The algebraic string contains mismatched parentheses (extra left parenthesis)."); } else if (o == ')') { throw new FormatException("The algebraic string contains mismatched parentheses (extra right parenthesis)."); } else { AddToOutput(output, o); } } return(new string(output.ToArray())); }
public static Expression <Func <BigInteger> > ExpressionTree(string postfixNotationString) { if (string.IsNullOrWhiteSpace(postfixNotationString)) { throw new ArgumentException("Argument postfixNotationString must not be null, empty or whitespace.", "postfixNotationString"); } Stack <Expression> stack = new Stack <Expression>(); string sanitizedString = new string(postfixNotationString.Where(c => AllowedCharacters.Contains(c)).ToArray()); List <string> enumerablePostfixTokens = sanitizedString.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries).ToList(); foreach (string token in enumerablePostfixTokens) { if (token.Length < 1) { throw new Exception("Token.Length is less than one."); } BigInteger tokenValue = 0; bool parseSuccess = BigInteger.TryParse(token, out tokenValue); if (token.Length > 1) // Numbers > 10 will have a token length > 1 { if (InfixNotation.IsNumeric(token) && parseSuccess) { stack.Push(Expression.Constant(tokenValue)); } else { throw new Exception("Operators and operands must be separated by a space."); } } else { char tokenChar = token[0]; if (InfixNotation.Numbers.Contains(tokenChar) && parseSuccess) { stack.Push(Expression.Constant(tokenValue)); } else if (InfixNotation.Operators.Contains(tokenChar)) { if (stack.Count < 2) // There must be two operands for the operator to operate on { throw new FormatException("The algebraic string has not sufficient values in the expression for the number of operators; There must be two operands for the operator to operate on."); } Expression left = stack.Pop(); Expression right = stack.Pop(); Expression operation = null; /* * // ^ token uses Math.Pow, which both gives and takes double, hence convert * if (tokenChar == '^') * { * if (left.Type != typeof(double)) * { * left = Expression.Convert(left, typeof(double)); * } * if (right.Type != typeof(double)) * { * right = Expression.Convert(right, typeof(double)); * } * } * else // Math.Pow returns a double, so we must check here for all other operators * { * if (left.Type != typeof(BigInteger)) * { * left = Expression.Convert(left, typeof(BigInteger)); * } * if (right.Type != typeof(BigInteger)) * { * right = Expression.Convert(right, typeof(BigInteger)); * } * } */ if (tokenChar == '+') { operation = Expression.AddChecked(left, right); } else if (tokenChar == '-') { operation = Expression.SubtractChecked(left, right); } else if (tokenChar == '*') { operation = Expression.MultiplyChecked(left, right); } else if (tokenChar == '/') { operation = Expression.Divide(left, right); } else if (tokenChar == '^') { operation = Expression.Power(left, right); } if (operation != null) { stack.Push(operation); } else { throw new Exception("Value never got set."); } } else { throw new Exception(string.Format("Unrecognized character '{0}'.", tokenChar)); } } } if (stack.Count == 1) { return(Expression.Lambda <Func <BigInteger> >(stack.Pop())); } else { throw new Exception("The input has too many values for the number of operators."); } } // method
} // method public static BigInteger Evaluate(string postfixNotationString) { if (string.IsNullOrWhiteSpace(postfixNotationString)) { throw new ArgumentException("Argument postfixNotationString must not be null, empty or whitespace.", "postfixNotationString"); } Stack <string> stack = new Stack <string>(); string sanitizedString = new string(postfixNotationString.Where(c => AllowedCharacters.Contains(c)).ToArray()); List <string> enumerablePostfixTokens = sanitizedString.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries).ToList(); foreach (string token in enumerablePostfixTokens) { if (token.Length > 0) { if (token.Length > 1) { if (InfixNotation.IsNumeric(token)) { stack.Push(token); } else { throw new Exception("Operators and operands must be separated by a space."); } } else { char tokenChar = token[0]; if (InfixNotation.Numbers.Contains(tokenChar)) { stack.Push(tokenChar.ToString()); } else if (InfixNotation.Operators.Contains(tokenChar)) { if (stack.Count < 2) { throw new FormatException("The algebraic string has not sufficient values in the expression for the number of operators."); } string r = stack.Pop(); string l = stack.Pop(); BigInteger rhs = BigInteger.MinusOne; BigInteger lhs = BigInteger.MinusOne; bool parseSuccess = BigInteger.TryParse(r, out rhs); parseSuccess &= BigInteger.TryParse(l, out lhs); parseSuccess &= (rhs != BigInteger.MinusOne && lhs != BigInteger.MinusOne); if (!parseSuccess) { throw new Exception("Unable to parse valueStack characters to Int32."); } BigInteger value = BigInteger.MinusOne; if (tokenChar == '+') { value = lhs + rhs; } else if (tokenChar == '-') { value = lhs - rhs; } else if (tokenChar == '*') { value = lhs * rhs; } else if (tokenChar == '/') { value = lhs / rhs; } else if (tokenChar == '^') { value = HelperClass.Pow(lhs, rhs); } if (value != BigInteger.MinusOne) { stack.Push(value.ToString()); } else { throw new Exception("Value never got set."); } } else { throw new Exception(string.Format("Unrecognized character '{0}'.", tokenChar)); } } } else { throw new Exception("Token length is less than one."); } } if (stack.Count == 1) { BigInteger result = 0; if (!BigInteger.TryParse(stack.Pop(), out result)) { throw new Exception("Last value on stack could not be parsed into an integer."); } else { return(result); } } else { throw new Exception("The input has too many values for the number of operators."); } } // method