用于计算四则混合运算表达式的递归函数第二版
更新于2007-08-28 by billow3(QQ:41965573)
注:本文在发表时稍作了排版,如果有因排版引起的代码工作不正常请来信告知我们
#include <math.h> #pragma warn -8060 // 屏蔽编译时的 Possibly incorrect assignment 警告 AnsiString __fastcall Calc(String sExp) { // 计算不带变量的四则混合运算表达式(支持取整int和圆整round函数,支持负操作数) // 正数不许带正号 int posL, pos, posR, posM; // pos->当前考虑的运算符的位置 // posL->当前考虑的运算符之前最近的运算符的位置 // posR->当前考虑的运算符之后最近的运算符的位置 // posM->圆整函数中逗号的位置 String sTmp, sL, sR; // sL->当前考虑的运算符的左操作数字符串,sR->当前考虑的运算符的右操作数字符串 bool IsMinus; // IsMinus->当前*/序列的符号 sExp = sExp.LowerCase(); if(sExp.AnsiPos("error")) return(sExp); while(pos = sExp.AnsiPos(" ")) sExp = sExp.Delete(pos, 1); // 去除表达式中的空格 if(sExp.IsEmpty()) return("0"); while((pos = sExp.AnsiPos("[")) > 0 || (pos = sExp.AnsiPos("{")) > 0) // 统一左括号为( sExp = sExp.SubString(1, pos - 1) + "(" + sExp.SubString(pos + 1, sExp.Length()); while((pos = sExp.AnsiPos("]")) > 0 || (pos = sExp.AnsiPos("}")) > 0) // 统一右括号为) sExp = sExp.SubString(1, pos - 1) + ")" + sExp.SubString(pos + 1, sExp.Length()); // 以下处理round圆整函数 while(pos = sExp.AnsiPos("round(")) { posL = pos + 5; while(posM = sExp.SubString(posL + 1, sExp.Length()).AnsiPos("round(")) posL = posL + posM + 5; // 最后一个round之后的位置 for(posM = posL + 2; !sExp.IsDelimiter(",", posM) && posM <= sExp.Length(); posM++); // round后第一个, 的位置 if(posM == 0) return("error:round没有配对的逗号, 公式错!"); for(posR = posM + 2; !sExp.IsDelimiter(")", posR) && posR <= sExp.Length(); posR++); // 逗号后第一个)的位置 // posR不从posM + 1而从posM + 2开始搜索,是为了应对操作数为负的情况 sExp = sExp.SubString(1, posL - 6) + floor(Calc(sExp.SubString(posL + 1, posM - posL - 1)).ToDouble() * pow(10, sExp.SubString(posM + 1, posR - posM - 1).ToDouble()) + 0.5) / pow(10, sExp.SubString(posM + 1, posR - posM - 1).ToDouble()) + sExp.SubString(posR + 1, sExp.Length()); } // 处理括号:递归计算括号中的表达式,最后消去括号 while(posL = sExp.LastDelimiter("(")) // 最里层( { sTmp = sExp.SubString(posL + 1, sExp.Length()); posR = sTmp.AnsiPos(")"); // 最里层) if(posR == 0) return("error:没有配对的), 公式错!"); sExp = sExp.SubString(1, posL - 1) + Calc(sTmp.SubString(1, posR - 1) |