예제 #1
0
        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);
            }
        }
예제 #2
0
        // 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
            }
        }
예제 #3
0
        //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));
        }
예제 #4
0
        //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.
        }
예제 #5
0
        //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);
            }
        }
예제 #6
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)
            {
                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);
        }
예제 #7
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);
        }
예제 #8
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
         }
     }
 }
예제 #9
0
        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
        }