private Node determineNode(string expression, int operandBegin, int i) { string operandName = expression.Substring(operandBegin, i - operandBegin); // Figure out if operand is constant or variable valued if (65 < expression[operandBegin]) { // We know that the operand, left of current operator, is a variable if (variableDictionary.ContainsKey(operandName) == true) { VarNode newNode = new VarNode(operandName, variableDictionary[operandName]); return(newNode); } else { VarNode newNode = new VarNode(operandName, 0); variableDictionary.Add(operandName, newNode.NodeValue); return(newNode); } } else { // We know that the operand, left of current operator, is a constant ConstNode newNode = new ConstNode(operandName, Convert.ToDouble(operandName)); return(newNode); } }
// public facing interface to set a variable node. public void SetVar(string varName, double varValue) { VarNode search = new VarNode(varName, varValue); //creating a node so that it is easier to compare between nodes. This node stores the value of the new variable if (root as OpNode != null) //if root is an operator node { SetVarNode(ref search, root as OpNode); } else if (VariableNodeCompare(search, root)) //if root is a Variable node and has the same variable name { (root as VarNode).Value = varValue; //sets the root value to the new variable } }
//Build node private static Node BuildSimple(string term) { double num; //if term is a number, put in a constNode if (double.TryParse(term, out num)) { return(new ConstNode(num)); } //if term is a variable, put in varNode VarNode node = new VarNode(term); return(new VarNode(term)); }
//returns true only if both nodes are VariableNodes and the names of the variables are the same. public bool VariableNodeCompare(ExpNode inputLeftNode, ExpNode inputRightNode) { VarNode leftNodeAsVar = inputLeftNode as VarNode; VarNode righttNodeAsVar = inputRightNode as VarNode; if (leftNodeAsVar == null || righttNodeAsVar == null) //both are null, so they are not both variableNodes, and are not equal { return(false); } if (leftNodeAsVar.Variable == righttNodeAsVar.Variable) //variables match the same string { return(true); } return(false); //if the nodes do not contain the same string. }
//simple function that turns a string into a Data node. protected virtual ExpNode MakeDataNode(string operand) { double number; bool isDouble = double.TryParse(operand, out number); //only stores the operand in number if it is actually a double if (isDouble) { ValNode numNode = new ValNode(number); //makes a Numerical node with the operand's value return(numNode); } else { VarNode varNode = new VarNode(operand); //makes a variable node with the operands variable name. return(varNode); } }
private double Eval(Node node) { //Evaluate based on the kind of node ConstNode constnode = node as ConstNode; if (constnode != null) { return(constnode.OpValue); } VarNode varnode = node as VarNode; if (varnode != null) { try { return(variableDict[varnode.Name]); } catch { Console.WriteLine("Variable " + varnode.Name + " has not been defined. Continuing evaluation with variable equal to 0."); } } OpNode opnode = node as OpNode; if (opnode != null) { switch (opnode.Op) { case '+': return(Eval(opnode.Left) + Eval(opnode.Right)); case '-': return(Eval(opnode.Left) - Eval(opnode.Right)); case '*': return(Eval(opnode.Left) * Eval(opnode.Right)); case '/': return(Eval(opnode.Left) / Eval(opnode.Right)); } } return(0); }
private double Eval(Node node) { //Evaluate based on the kind of node ConstNode constnode = node as ConstNode; if (constnode != null) { return(constnode.OpValue); } VarNode varnode = node as VarNode; if (varnode != null) { // used to be a try/catch, but now we set every new variable to 0 when the tree is made, so there will always be a value to obtain. return(variableDict[varnode.Name]); } OpNode opnode = node as OpNode; if (opnode != null) { switch (opnode.Op) { case '+': return(Eval(opnode.Left) + Eval(opnode.Right)); case '-': return(Eval(opnode.Left) - Eval(opnode.Right)); case '*': return(Eval(opnode.Left) * Eval(opnode.Right)); case '/': return(Eval(opnode.Left) / Eval(opnode.Right)); } } return(0); }
// recursive function to set a variable node. protected void SetVarNode(ref VarNode input, OpNode node) { if (VariableNodeCompare(input, node.left)) //if the left node is a Variable node and has the same variable name { (node.left as VarNode).Value = input.Value; } else if (VariableNodeCompare(input, node.right)) //if the right node is a Variable node and has the same variable name { (node.right as VarNode).Value = input.Value; } else { if (node.right as OpNode != null) //if the right side node is an operator node { SetVarNode(ref input, node.right as OpNode); //check right subtree } if (node.left as OpNode != null) //if the right side node is an operator node { SetVarNode(ref input, node.left as OpNode); //check right subtree } } }
public ExpTree(string expression) { Stack <string> equationStack = new Stack <string>(); Stack <string> treeStack = new Stack <string>(); Stack <Node> buildTree = new Stack <Node>(); string tempString = ""; //format expression to work with parser expression = "(" + expression + ")"; char[] tokens = expression.ToCharArray(); //build stack from parsed expression - shunting yard algorithm for (int i = 0; i < tokens.Length; i++) { if (tokens[i] == '(') { equationStack.Push(tokens[i].ToString()); } else if (tokens[i] == ')') // doesn't push ")" to equation stack { while (equationStack.Peek() != "(") // pop until lhs bracket is found { treeStack.Push(equationStack.Pop()); // add right child and operator } equationStack.Pop(); // get rid of "(" } else if (operators.Contains(tokens[i].ToString())) // current token is an operator { while (equationStack.Peek() != "(" && (!operators.Contains(equationStack.Peek()) || (getPrecedence(tokens[i].ToString()) < getPrecedence(equationStack.Peek())) || /*check if stack top is operator of higher precedence*/ (getPrecedence(tokens[i].ToString()) == getPrecedence(equationStack.Peek())))) { treeStack.Push(equationStack.Pop()); } equationStack.Push(tokens[i].ToString()); } else // integer or variable { // get numbers with multiple digits (will always execute at least once) while (tokens[i] != '(' && tokens[i] != ')' && !operators.Contains(tokens[i].ToString())) { tempString += tokens[i]; i++; } if (tokens[i] == '(' || tokens[i] == ')' || operators.Contains(tokens[i].ToString())) { i--; //move back so token isn't skipped in next iteration } equationStack.Push(tempString); tempString = ""; } } equationStack.Clear(); //reverse stack to get postfix expression while (treeStack.Count != 0) { equationStack.Push(treeStack.Pop()); } //build tree while (equationStack.Count != 0) //equationStack now contains postfix expression { tempString = equationStack.Pop(); if (operators.Contains(tempString)) //make opNode { OpNode newNode = new OpNode(tempString); if (buildTree.Count >= 2) { newNode.right = buildTree.Pop(); newNode.left = buildTree.Pop(); buildTree.Push(newNode); } } else { if (tempString.All(Char.IsDigit)) //make valNode { ValNode newNode = new ValNode(tempString); buildTree.Push(newNode); } else //make varNode { char let = Char.ToUpper(tempString[0]); string row = tempString.Substring(1); tempString = let + row; if (!varDict.ContainsKey(tempString)) { varDict[tempString] = 0; //initialize all variables to 0 } VarNode newNode = new VarNode(tempString); buildTree.Push(newNode); varList.Add(tempString); //add to list of cell references } } } this.root = buildTree.Pop(); //final item in stack will be root node pointing to subtrees }