表达式求值
#include "stdafx.h" #include<iostream> #include<stack> using namespace std; #define ERROR -1 #define RIGHT 0 #define CHECK_EMPTY(stack) if (stack.empty()) \ {\ return ERROR;\ } //用来输出提示信息的 #define PRINT_STEP 0 //判断是否为操作符 int IsOperator(char cTemp) { switch (cTemp) { case '+': case '-': case '*': case '/': case '(': case ')':return 1; default:return 0; } } int JudgeOperatorPriority(char cOpe) { switch (cOpe) { case '+': case '-':return 1; case '*': case '/':return 2; default:return ERROR; } } int Calculate(int lNum, int rNum, char cOper) { int iResule = 0; switch (cOper) { case '+': iResule = lNum + rNum; break; case '-': iResule = lNum - rNum; break; case '*': iResule = lNum * rNum; break; case '/': iResule = lNum / rNum; break; default: return ERROR; } return iResule; } //进行优先级高的运算 int PartialCalc(stack<int>& iStack, stack<char>& cStack) { int rNum = 0, lNum = 0, iResult = 0; char cOper; CHECK_EMPTY(iStack); rNum = iStack.top(); iStack.pop(); CHECK_EMPTY(iStack); lNum = iStack.top(); iStack.pop(); CHECK_EMPTY(cStack); cOper = cStack.top(); cStack.pop(); iResult = Calculate(lNum, rNum, cOper); iStack.push(iResult); return RIGHT; } int CompareOperator(char cStackOper, char cNewOper) { return JudgeOperatorPriority(cStackOper) < JudgeOperatorPriority(cNewOper); } /***************************************************** *函数名:ExpCalc *功 能:给表达式求值 *入 参:pcExp: 表达式字符串,比如 1+2*3+4*5+6 *出 参:piResult: 表达式的运算结果 *返回值:RIGHT 执行成功 ERROR 执行失败 *创建日期:2017.3.11 *******************************************************/ int ExpCalc(char *pcExp, int *piResult) { if (PRINT_STEP) { cout << pcExp << endl; } if (pcExp == NULL || piResult == NULL) { return ERROR; } //用来保存操作数 stack<int>iStackNum; //用来保存操作符 stack<char>cStackOpe; int i = 0; int iRet; //当表达式第一个数为负数的时候,在操作数栈中压入一个0 if (pcExp[0] == '+' || pcExp[0] == '-') { iStackNum.push(0); } while (pcExp[i]) { //如果字符为数字 if (pcExp[i] - '0' >= 0 && pcExp[i] - '0' <= 9) { if (PRINT_STEP) { cout << "num=" << pcExp[i] << endl; } int iSum = pcExp[i] - '0'; i++; while (pcExp[i] - '0' >= 0 && pcExp[i] - '0' <= 9) { iSum *= 10; iSum += (pcExp[i] - '0'); i++; } iStackNum.push(iSum); if (PRINT_STEP) { cout << "iStackNum.push=" << iSum << endl; } continue; }//end 最外层if //如果字符为操作符 else if (IsOperator(pcExp[i])) { if (PRINT_STEP) { cout << "operator = " << pcExp[i] << endl; } //如果刚开始运算栈中没用运算符 //或者比较栈中的运算符和新的运算符的优先级 //如果栈顶运算符优先级比新的运算符低,直接压入栈中 if (cStackOpe.empty()|| CompareOperator(cStackOpe.top(), pcExp[i]) ||pcExp[i]=='(') { cStackOpe.push(pcExp[i]); i++; if (cStackOpe.top() == '(' && (pcExp[i] == '-' || pcExp[i] == '+')) { iStackNum.push(0); } continue; } else if (pcExp[i] == ')') { while (cStackOpe.top() != '(') { //开始进行部分的运算 iRet=PartialCalc(iStackNum, cStackOpe); if (iRet != RIGHT) { return iRet; } CHECK_EMPTY(cStackOpe); } cStackOpe.pop(); i++; continue; } //如果栈顶运算符优先级比新的运算符高 else { //开始进行部分的运算 iRet = PartialCalc(iStackNum, cStackOpe); if (iRet != RIGHT) { return iRet; } continue; } }//end else if (IsOperator(pcExp[i])) else { //忽略所有不是操作数或者运算符的字符 i++; } }//end while(acExp[i]) //如果运算符栈中用运算符,继续运算,直到运算栈为空 while (!cStackOpe.empty()) { iRet=PartialCalc(iStackNum, cStackOpe); if (iRet != RIGHT) { return iRet; } } if (iStackNum.size() > 1) { return ERROR; } *piResult = iStackNum.top(); return RIGHT; } int main() { int iRet = 0;; ExpCalc("1+2*3+4*5*6+7*8-100", &iRet); cout << "1+2*3+4*5*6+7*8-100 = " << iRet << endl; cout << "Check: " << (1 + 2 * 3 + 4 * 5 * 6 + 7 * 8 - 100) << endl; ExpCalc("100+90*12*2-1000", &iRet); cout << "100+90*12*2-1000 = " << iRet << endl; cout << "Check: " << (100 + 90 * 12 * 2 - 1000) << endl; //增加括号运算符 ExpCalc("(1+2)*(3+4)*5*6+7*8-100", &iRet); cout << "(1+2)*(3+4)*5*6+7*8-100 = " << iRet << endl; cout << "Check: " << ((1 + 2)*(3 + 4) * 5 * 6 + 7 * 8 - 100) << endl; //增加负数处理 char szExp3[] = "-1+ 3*((-2*3+4)*(5+6*(3+2)*4+(-10)))-(100+4*5)*2"; ExpCalc(szExp3, &iRet); cout << szExp3 << " = " << iRet << endl; cout << "Check:" << (-1 + 3 * ((-2 * 3 + 4)*(5 + 6 * (3 + 2) * 4 + (-10))) - (100 + 4 * 5) * 2) << endl; cout << endl; //非法表达式 char szExp4[] = "1-+2*3"; char szExp4[] = "1+2*(3+4)5"; char szExp4[] = "1+2*(3+4"; char szExp4[] = "1+2*3+4*5)"; int iTmp = ExpCalc(szExp4, &iRet); if (iTmp) { cout << "Expression [" << szExp4 << "] error!" << endl; } else { cout << szExp4 << " = " << iRet << endl; } cout << endl; return 0; }