public override TreeNode FactoryMethod(string expression) { OpNodeFactory opNodeFactory = new ConcreteOpNodeFactory(); OperatorNode @operator = opNodeFactory.FactoryMethod(expression); if (@operator != null) { return(@operator); } else { bool int_success = Int32.TryParse(expression, out int int_result), double_success = Double.TryParse(expression, out double double_result); if (int_success) { return(new ValueNode(int_result)); } else if (double_success) { return(new ValueNode(double_result)); } else { return(new CellReferenceNode(expression)); } } }
public double Evaluate() { // If the node is a constantNode(a number), then simply return its value ConstantNode constantNode = this.Root as ConstantNode; if (constantNode != null) { return(constantNode.Value); } // If the node is a variableNode then return the value in the dictionary correspondingly VariableNode variableNode = this.Root as VariableNode; if (variableNode != null) { return(this.Variables[variableNode.Name]); } // it is an operator node if we came here OperatorNode operatorNode = this.Root as OperatorNode; if (operatorNode != null) { OperatorNode op = this.Root as OperatorNode; if (op != null) { return(op.Evaluate()); } } throw new NotSupportedException(); }
public string ShuntingYard(string expression) { Stack <string> stack = new Stack <string>(); string result = string.Empty; char c; for (int i = 0; i < expression.Length; i++) { c = expression[i]; if (c == '+' || c == '-' || c == '*' || c == '/' || c == '^') // Incoming symbols is an operator { OperatorNode op = new OperatorNode(c); if (stack.Count == 0 || stack.Peek() == "(") // 4. Stack is empty or stack top = Left parenthesis { stack.Push(c.ToString()); } else if (stack.Count != 0) { OperatorNode stackOp = new OperatorNode(stack.Peek().ToCharArray()[0]); if ((op.Precedence > stackOp.Precedence) || (op.Precedence == stackOp.Precedence && stackOp.Associativity == "Right")) // 5. { stack.Push(c.ToString()); } else if ((op.Precedence < stackOp.Precedence) || (op.Precedence == stackOp.Precedence && stackOp.Associativity == "Left")) // 6. { while (stack.Count != 0 && ((op.Precedence < stackOp.Precedence) || (op.Precedence == stackOp.Precedence && stackOp.Associativity == "Left"))) { result += stack.Pop(); } stack.Push(c.ToString()); } } } else if (c == '(') // 2. Incoming symbols is a left parenthesis { stack.Push(c.ToString()); } else if (c == ')') // 3. Incoming symbols is a right parenthesis { while (stack.Peek() != "(") { result += stack.Pop(); } stack.Pop(); } else // 1. Incoming symbols is an operand { result += c; } } while (stack.Count != 0) { result += stack.Pop(); } return(result); }
/************************************************************ * This is a recursive function which builds the entire * expression tree from the bottom to the top. * Here's how the general idea of how the function works: * 1. Segment the expression with "+" and "-" being * the delimiters then either construct a node with * those segments or build a tree out of it (by calling this * recursive function) depending on which one's the * appropriate option and connect those nodes/trees together * appropriately but don't segment anything within parenthesis. * 2. Repeat #1 but use "*" and "/" as the delimiters. * 3. If an sub_expression with paranthesis as the first * and last element get passed to this function, go back * to #1. * 4. Eventually a tree will be constructed from the * bottom to the top. ************************************************************/ private Node ConstructTree(string sub_expression, bool using_multiply_divide_operators) { List <string> expression_pieces = new List <string>(); char[] contents = sub_expression.ToCharArray(); char operator1 = '+', operator2 = '-'; if ('(' == contents[0] && ')' == contents[contents.Length - 1]) { sub_expression = sub_expression.Substring(1, sub_expression.Length - 2); contents = sub_expression.ToCharArray(); using_multiply_divide_operators = false; } if (using_multiply_divide_operators) { operator1 = '*'; operator2 = '/'; } /************************************************************ * Base Case: Expression has no parenthesis and has * no + or - operators ************************************************************/ if (!sub_expression.Contains("+") && !sub_expression.Contains("-") && !sub_expression.Contains("(")) { string[] split_pieces_from_multiply_operator = sub_expression.Split('*'); List <string> split_pieces_from_multiply_operator_list = new List <string>(); for (int i = 0; i < split_pieces_from_multiply_operator.Length; i++) { split_pieces_from_multiply_operator_list.Add(split_pieces_from_multiply_operator[i]); split_pieces_from_multiply_operator_list.Add("*"); } split_pieces_from_multiply_operator_list.RemoveAt(split_pieces_from_multiply_operator_list.Count - 1); for (int i = 0; i < split_pieces_from_multiply_operator_list.Count; i++) { if (split_pieces_from_multiply_operator_list[i].Contains("/")) { string[] split_pieces_from_divide_operator = split_pieces_from_multiply_operator_list[i].Split('/'); List <string> split_pieces_from_divide_operator_list = new List <string>(); for (int j = 0; j < split_pieces_from_divide_operator.Length; j++) { expression_pieces.Add(split_pieces_from_divide_operator[j]); expression_pieces.Add("/"); } expression_pieces.RemoveAt(expression_pieces.Count - 1); } else { expression_pieces.Add(split_pieces_from_multiply_operator_list[i]); } } } else { int cut_start_i = 0; for (int i = 0; i < contents.Length; i++) { if ('(' == contents[i]) { int parenthesis_start_i = i; int parenthesis_count = 1; while (0 != parenthesis_count) { i++; if ('(' == contents[i]) { parenthesis_count++; } else if (')' == contents[i]) { parenthesis_count--; } } } else if (operator1 == contents[i] || operator2 == contents[i]) { expression_pieces.Add(sub_expression.Substring(cut_start_i, i - cut_start_i)); expression_pieces.Add(Convert.ToString(contents[i])); cut_start_i = i + 1; } } expression_pieces.Add(sub_expression.Substring(cut_start_i, sub_expression.Length - cut_start_i)); } Node current_left_node = MakeNodeWithValue(expression_pieces[0]); if (null == current_left_node) { current_left_node = ConstructTree(expression_pieces[0], true); } for (int i = 1; i < expression_pieces.Count; i += 2) { OperatorNode current_operator = new OperatorNode(expression_pieces[i]); Node current_right_node = MakeNodeWithValue(expression_pieces[i + 1]); if (null == current_right_node) { current_right_node = ConstructTree(expression_pieces[i + 1], true); } current_operator.Left = current_left_node; current_operator.Right = current_right_node; current_left_node = current_operator; } return(current_left_node); }
public Node ConstructTree(string pre_expression) { // This block is responsible for finding all the variables in the expression List <string> temp = new List <string>(); string m = string.Empty; char p; for (int k = 0; k < pre_expression.Length; k++) { p = pre_expression[k]; if (p == '(' || p == ')') { } else if (p != '+' && p != '-' && p != '*' && p != '/') { m += p; } else { temp.Add(m); m = ""; } } temp.Add(m); // Take the original expression string expression = ShuntingYard(pre_expression); // Get its postfix notation // This block is responsible for building the tree Stack <Node> stack = new Stack <Node>(); Node n = this.Root; char c; string x = ""; int y = 0; // Read until there is nothing left to read for (int i = 0; i < expression.Length; i++) { c = expression[i]; // Read char by char // If char read is an operator if (c == '+' || c == '-' || c == '*' || c == '/') { Node tree1 = null; if (stack.Count != 0) { tree1 = stack.Pop(); } Node tree2 = null; if (stack.Count != 0) { tree2 = stack.Pop(); } OperatorNode op = new OperatorNode(c); op.Right = tree1; op.Left = tree2; n = op; stack.Push(op); } else { // If its any other things (variables) x += c; // Keep making the string until it is one of the variables we need if (x == temp[y]) { y++; // This part is where we deal with single expressions without Operators // So automatically, we know that it will either be a ConstantNode(a number) or a VariableNode(a name) double number; // If the expression is a ConstantNode if (double.TryParse(x, out number)) { // Insert the expression into the dictionary //if (!this.Variables.ContainsKey(x)) //{ // this.Variables.Add(x, number); //} ConstantNode cn = new ConstantNode(); cn.Value = number; n = cn; stack.Push(n); } // If the expression is VariableNode else { // Insert the expression into the dictionary if (!this.Variables.ContainsKey(x)) { this.Variables.Add(x, 0.0); } VariableNode vn = new VariableNode(Variables); vn.Name = x; n = vn; stack.Push(n); } x = ""; } } } return(n); }