表达式求值

#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;
}

 

posted @ 2017-03-13 11:02  菜鸟也有高飞的时候  阅读(272)  评论(0编辑  收藏  举报