コード例 #1
0
        /// <summary>
        /// 根据算术表达式创建二叉树
        /// </summary>
        /// <param name="str"></param>
        /// <param name="p"></param>
        /// <param name="q"></param>
        /// <param name="tail"></param>
        void createTreenode(TreeNode node, string str, int p, int q, int tail, ref OP[] Aop)
        {
            //p,q分别标志Aop的首尾
            int i = 0, find = 0;

            if (str[p] == '(' && str[q] == ')')
            {
                for (int j = tail; j >= 0; j--)
                {
                    if (Aop[j].operation != null && Aop[j].location >= p && Aop[j].location <= q)
                    {
                        Aop[j].location--;
                        Aop[j].index--;
                    }
                }
                str = str.Substring(p + 1, q - p - 1);
                q   = q - 2;
            }
            string tr     = "";
            string substr = "";

            if (istrigonometric(str, p, q, ref tr, tail, ref Aop))
            {
                TreeNode subnode = new TreeNode();
                if (tr == "sin" || tr == "cos" || tr == "tan")
                {
                    substr = str.Substring(p + 4, q - p - 4);
                }
                if (tr == "ln")
                {
                    substr = str.Substring(p + 3, q - p - 3);
                }
                if (tr == "sqrt")
                {
                    substr = str.Substring(p + 5, q - p - 5);
                }
                for (int j = tail; i >= 0; i--)
                {
                    if (Aop[i].operation != null && Aop[i].location >= p && Aop[i].location <= q)
                    {
                        Aop[i].index = -1;
                    }
                }
                OP[] Bop   = new OP[100];
                int  tail1 = Sortop1(substr, ref Bop);
                createTreenode(subnode, substr, 0, substr.Length - 1, tail1, ref Bop);
                switch (tr)
                {
                case "sin":
                    node.data.Number = Math.Sin(caculate(subnode));
                    break;

                case "cos":
                    node.data.Number = Math.Cos(caculate(subnode));
                    break;

                case "tan":
                    node.data.Number = Math.Tan(caculate(subnode));
                    break;

                case "ln":
                    node.data.Number = Math.Log(caculate(subnode));
                    break;

                case "sqrt":
                    node.data.Number = Math.Sqrt(caculate(subnode));
                    break;
                }
                node.lChild = null;
                node.rChild = null;
                return;
            }
            if (isnum(str, p, q))//如果数据仅含运算数
            {
                //创建头节点,并将数据位置为str2float
                node.data.Number = str2float(str, p, q);
                node.lChild      = null;
                node.rChild      = null;
                return;
            }
            else if (isoperator(str, p, q))//如果数据仅含运算符
            {
                return;
            }
            else
            {
                for (int j = 0; j <= index; j++) //按照括号一层一层地找
                {
                    for (i = tail; i >= 0; i--)  //从后往前找,才符合运算的法则,前面先算后面后算
                    {
                        if (Aop[i].index == j && ((Aop[i].operation == "+") || (Aop[i].operation == "-")) && Aop[i].location >= p && Aop[i].location <= q)
                        {
                            find++;
                            Aop[i].index       = -1;
                            node.lChild        = new TreeNode();
                            node.rChild        = new TreeNode();
                            node.data.Operator = Aop[i].operation;
                            createTreenode(node.lChild, str, p, Aop[i].location - 1, tail, ref Aop);
                            createTreenode(node.rChild, str, Aop[i].location + 1, q, tail, ref Aop);
                        }
                    }
                    if (find == 0)
                    {
                        for (i = tail; i >= 0; i--)
                        {
                            if (Aop[i].index == j && ((Aop[i].operation == "*") || (Aop[i].operation == "/")) && Aop[i].location >= p && Aop[i].location <= q)
                            {
                                find++;
                                Aop[i].index       = -1;
                                node.lChild        = new TreeNode();
                                node.rChild        = new TreeNode();
                                node.data.Operator = Aop[i].operation;
                                createTreenode(node.lChild, str, p, Aop[i].location - 1, tail, ref Aop);
                                createTreenode(node.rChild, str, Aop[i].location + 1, q, tail, ref Aop);
                            }
                        }
                    }
                    if (find == 0)
                    {
                        for (i = tail; i >= 0; i--)
                        {
                            if (Aop[i].index == j && (Aop[i].operation == "^") && Aop[i].location >= p && Aop[i].location <= q)
                            {
                                Aop[i].index       = -1;
                                node.lChild        = new TreeNode();
                                node.rChild        = new TreeNode();
                                node.data.Operator = Aop[i].operation;
                                createTreenode(node.lChild, str, p, Aop[i].location - 1, tail, ref Aop);
                                createTreenode(node.rChild, str, Aop[i].location + 1, q, tail, ref Aop);
                            }
                        }
                    }
                }
            }
        }
コード例 #2
0
ファイル: Form1.cs プロジェクト: nardnob/Calculator
        private void setOperation(OP in_op)
        {
            if (in_op != OP.CLRENTRY &&
                in_op != OP.BACKSPACE &&
                in_op != OP.MRECALL &&
                in_op != OP.PER)
            {
                //solve the current display
                equateDisplay();
            }

            bool newOpIn = in_op == OP.ADD || in_op == OP.SUB || in_op == OP.MUL || in_op == OP.DIV;

            //set whether or not an op is displaying (like + - * or /).. useful for parsing string
            if (newOpIn || (displayedOp && (in_op == OP.MRECALL || in_op == OP.PER)))
            {
                displayedOp = true;
            }
            else
            if (in_op != OP.BACKSPACE)
            {
                displayedOp = false;
            }

            //set the operation for the next display
            if (in_op != OP.BACKSPACE &&
                in_op != OP.MRECALL &&
                in_op != OP.PER)
            {
                currentOperation = in_op;
            }

            if (in_op != OP.BACKSPACE &&
                in_op != OP.MRECALL &&
                in_op != OP.PER)
            {
                hasNum = false;
            }

            if (in_op != OP.MRECALL)
            {
                endingOp = false;
            }

            //display the operation in the display
            switch (in_op)
            {
            case OP.ADD:
                //textBox_display.Text = "+ ";
                soonTxt = "+ ";
                displayText();
                break;

            case OP.SUB:
                //textBox_display.Text = "- ";
                soonTxt = "- ";
                displayText();
                break;

            case OP.DIV:
                //textBox_display.Text = "/ ";
                soonTxt = "/ ";
                displayText();
                break;

            case OP.MUL:
                //textBox_display.Text = "* ";
                soonTxt = "* ";
                displayText();
                break;

            case OP.EQU:
                endingOp = true;
                //textBox_display.Text = currentValue.ToString();
                soonTxt = currentValue.ToString();
                displayText();
                hasNum = false;
                break;

            case OP.RECIP:
                endingOp     = true;
                currentValue = 1 / currentValue;
                //textBox_display.Text = currentValue.ToString();
                soonTxt = currentValue.ToString();
                displayText();
                hasNum = false;
                break;

            case OP.SQRT:
                endingOp     = true;
                currentValue = Math.Sqrt(currentValue);
                //textBox_display.Text = currentValue.ToString();
                soonTxt = currentValue.ToString();
                displayText();
                hasNum = false;
                break;

            case OP.INV:
                endingOp      = true;
                currentValue *= -1;
                //textBox_display.Text = currentValue.ToString();
                soonTxt = currentValue.ToString();
                displayText();
                hasNum = false;
                break;

            case OP.CLR:
                //textBox_display.Text = "0";
                soonTxt = "0";
                displayText();
                currentValue     = 0;
                currentOperation = OP.NONE;
                //memoryValue = 0;
                //memoryStored = false;
                //textBox_memory.Text = "";
                break;

            case OP.CLRENTRY:
                //textBox_display.Text = currentValue.ToString();
                soonTxt = currentValue.ToString();
                displayText();
                endingOp = true;
                break;

            case OP.BACKSPACE:
                if (!hasNum)
                {
                    //textBox_display.Text = currentValue.ToString();
                    soonTxt = currentValue.ToString();
                    displayText();
                    endingOp = true;
                }
                else
                if (currentOperation != OP.NONE)
                {
                    //textBox_display.Text = textBox_display.Text.Substring(0, textBox_display.Text.Length - 2);
                    soonTxt = soonTxt.Substring(0, soonTxt.Length - 1);
                    displayText();
                    if (soonTxt.Length <= TO_NUM)
                    {
                        hasNum = false;
                    }
                }
                else
                if (soonTxt != "0")
                {
                    //textBox_display.Text = textBox_display.Text.Substring(0, textBox_display.Text.Length - 1);
                    soonTxt = soonTxt.Substring(0, soonTxt.Length - 1);
                    displayText();
                    if (soonTxt.Length == 0)
                    {
                        hasNum = false;
                        //textBox_display.Text = "0";
                        soonTxt = "0";
                        displayText();
                    }
                }
                break;

            case OP.PER:
                double newDigits = getDigits() * 0.01 * currentValue;
                if (displayedOp)
                {
                    soonTxt = soonTxt.Substring(0, TO_NUM) + newDigits.ToString("g");
                }
                else
                {
                    soonTxt = newDigits.ToString("g");
                }
                displayText();
                break;

            case OP.MSTORE:
                if (currentValue != 0)
                {
                    endingOp = true;
                    //textBox_display.Text = currentValue.ToString();
                    soonTxt = currentValue.ToString();
                    displayText();
                    hasNum              = false;
                    memoryValue         = currentValue;
                    memoryStored        = true;
                    textBox_memory.Text = "M";
                }
                else
                if (currentOperation == OP.NONE && soonTxt != "0")
                {
                    endingOp = true;
                    //textBox_display.Text = currentValue.ToString();
                    soonTxt = currentValue.ToString();
                    displayText();
                    hasNum              = false;
                    memoryValue         = Convert.ToDouble(soonTxt);
                    memoryStored        = true;
                    textBox_memory.Text = "M";
                }
                break;

            case OP.MADD:
                if (memoryStored)
                {
                    endingOp = true;
                    //textBox_display.Text = currentValue.ToString();
                    soonTxt = currentValue.ToString();
                    displayText();
                    hasNum       = false;
                    memoryValue += currentValue;
                }
                break;

            case OP.MCLEAR:
                textBox_memory.Text = "";
                memoryValue         = 0;
                memoryStored        = false;
                break;

            case OP.MRECALL:
                if (memoryStored && memoryValue != 0)
                {
                    //different cases
                    if (hasNum && currentOperation != OP.NONE) //typed an op and a num but not pressed equal.. hasNum && currentOperation != OP.NONE
                    {                                          //replace current typed num with the recalled num
                        endingOp = true;

                        //textBox_display.Text = textBox_display.Text.Substring(0, TO_NUM);
                        //textBox_display.Text += memoryValue.ToString();
                        soonTxt  = soonTxt.Substring(0, TO_NUM);
                        soonTxt += memoryValue.ToString();
                        displayText();

                        hasNum = true;
                    }
                    else
                    if (hasNum && currentOperation == OP.NONE) //typed a num but no op.. hasNum && currentOperation == OP.NONE
                    {                                          //replace current typed num with the recalled num
                        endingOp = true;
                        //textBox_display.Text = memoryValue.ToString();
                        soonTxt = memoryValue.ToString();
                        displayText();
                        hasNum = true;
                    }
                    else
                    if (currentOperation == OP.NONE)      //beginning with 0, !hasNum, currentOperation == OP.NONE
                    {                                     //replace 0 with the recalled num
                        endingOp = true;
                        //textBox_display.Text = memoryValue.ToString();
                        soonTxt = memoryValue.ToString();
                        displayText();
                        hasNum = true;
                    }
                    else                                  //typed an op but not a num.. !hasNum, currentOperation != OP.NONE
                    {                                     //enter the recalled number as the num
                        endingOp = true;

                        if (displayedOp)
                        {
                            //textBox_display.Text += memoryValue.ToString();
                            soonTxt += memoryValue.ToString();
                            displayText();
                            hasNum = true;
                        }
                        else
                        {
                            //textBox_display.Text = memoryValue.ToString();
                            soonTxt = memoryValue.ToString();
                            displayText();
                            currentValue = Convert.ToDouble(soonTxt);
                            hasNum       = false;
                        }
                    }
                }
                break;

            default:
                break;
            }
        }