Beispiel #1
0
 //给定堆栈和运算符,计算值
 public static void calculate(ref Stack <Fraction> StackNum, string op)
 {
     try
     {
         if (op == "#")
         //#是负号运算替换值
         {
             Fraction First  = StackNum.Pop();
             Fraction Result = 0 - First;
             StackNum.Push(Result);
         }
         else if (op == "+")
         {
             Fraction Second = StackNum.Pop();
             Fraction First  = StackNum.Pop();
             Fraction Result = First + Second;
             StackNum.Push(Result);
         }
         else if (op == "-")
         {
             Fraction Second = StackNum.Pop();
             Fraction First  = StackNum.Pop();
             Fraction Result = First - Second;
             StackNum.Push(Result);
         }
         else if (op == "×")
         {
             Fraction Second = StackNum.Pop();
             Fraction First  = StackNum.Pop();
             Fraction Result = First * Second;
             StackNum.Push(Result);
         }
         else if (op == "÷")
         {
             Fraction Second = StackNum.Pop();
             Fraction First  = StackNum.Pop();
             if (Second.GetMo() == 0)
             {
                 throw new MyException.OwnException("除数不能为0哦!");
             }
             Fraction Result = First / Second;
             StackNum.Push(Result);
         }
     }
     catch (System.InvalidOperationException)
     {
         throw new MyException.OwnException("啊,题目表达式出错了!");
     }
 }
Beispiel #2
0
        //修正树结构,并计算得出最后的值。
        //修正包括范围:
        //1.减法中产生负数的情况(包括 有括号 与 无括号式子)
        //2.除法中需要整除的情况(这里只会修复有括号式子,无括号式子的情况已经在生成时修复了)
        //3.除法出现除数为0的情况(全部修复)
        public Fraction AmendTreeAndCalculate(Node root, int leftRange)
        {
            if (root.Left == null && root.Right == null)
            {
                return((Fraction)root.Value);
            }
            switch (root.Value)
            {
            case "+": return(AmendTreeAndCalculate(root.Left, leftRange) + AmendTreeAndCalculate(root.Right, leftRange));

            case "-":
                Fraction LExp = AmendTreeAndCalculate(root.Left, leftRange);
                Fraction RExp = AmendTreeAndCalculate(root.Right, leftRange);
                //如果结果为负数的话且是没有括号的式子
                //不允许结果中出现负数的话,就把两颗子树翻转
                //并且要重新生成中缀表达式和最小表达式
                if ((RExp > LExp) & !HasNegative & HasBrack)
                {
                    Transfer(root);
                }
                //针对没有括号的情况
                else if ((RExp > LExp) & !HasNegative)
                {
                    root.Value = "+";
                    return(LExp + RExp);
                }
                return(LExp - RExp);

            case "×": return(AmendTreeAndCalculate(root.Left, leftRange) * AmendTreeAndCalculate(root.Right, leftRange));

            case "÷":
                Fraction divider = AmendTreeAndCalculate(root.Left, leftRange);
                Fraction divisor = AmendTreeAndCalculate(root.Right, leftRange);
                //如果发现被除数不是0,而除数是0的话,就翻转两颗子树
                if (divisor.GetMo() == 0 && divider.GetMo() != 0)
                {
                    Transfer(root);
                    return(0);
                }
                //如果不幸发现被除数和除数同时为0的话,那么还是默默地改掉这个符号吧...
                else if (divisor.GetMo() == 0 && divider.GetMo() == 0)
                {
                    //除法自此改名为加法
                    root.Value = "+";
                    return(0);
                }
                //如果在满足了有效性的条件下,突然发现老板加了任务:你必须给我搞个整除出来,咋办?
                if (!HasFrac)
                {
                    //如果你天生就能整除,我何必遭受这个罪呢...
                    if (divider.GetMo() % divisor.GetMo() == 0)
                    {
                        return(divider.GetMo() / divisor.GetMo());
                    }
                    //但如果你天生不能整除可咋办呢?
                    else
                    {
                        //求得左侧被除数随机化产生的一个因子
                        int    iRnd = DateTime.Now.Millisecond;
                        Random rand = new Random(iRnd);
                        //注意这里值域的下限
                        int  a   = rand.Next(leftRange, Math.Abs((int)divider.GetMo()));
                        long gcd = Fraction.GetGCD(divider.GetMo(), a);
                        //舍弃右侧原有子树,使用新的结点来代替,除法结果是 divider / gcd
                        root.Right = new Node(new Fraction(gcd, 1).ToString());
                        return(divider.GetMo() / gcd);
                    }
                }
                return(divider / divisor);

            default:
                throw new MyException.OwnDivException("啊呀呀,在计算的时候出了奇怪的错误。");
            }
        }