//给定堆栈和运算符,计算值 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("啊,题目表达式出错了!"); } }
//修正树结构,并计算得出最后的值。 //修正包括范围: //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("啊呀呀,在计算的时候出了奇怪的错误。"); } }