栈的应用之算术表达式求值

来源:互联网 发布:淘宝代运营提成几个点 编辑:程序博客网 时间:2024/05/01 21:17

栈是一种后进先出的数据结构。表达式求值是对栈的一个典型的应用。
对于如下一个表达式:

     1 + 2 * (3 + 4)

此算术表达式由一些操作符和操作数组成。其中,操作符有‘+’、‘*’、‘(’等,操作数有‘1’、‘2’、‘3’等。对于操作符来说,其运算是有优先级的。比如,上述表达式中,3+4应该先进行操作,将得到的结果再与2相乘。

算符间的优先关系如下:

运算符 + - * / ( ) # + > > < < < > > - > > < < < > > * > > > > < > > / > > > > < > > ( < < < < < = ) > > > > > > # > > < < < =

根据算符间的优先关系表,使用两个栈。一个栈为OPTR,存储运算符,另一个栈OPND,存储运算数。
程序运行过程如下:

  1. 初始化,将两个栈均置为空。将‘#’提前入OPTR栈。
  2. 读取表达式的每个字符。若读取内容为运算数,则将其转换为整数后加入OPND栈。若读取内容为运算符,则比较所读运算符和栈顶运算符的优先级大小,做以下处理:
    若栈顶运算符优先级比较低,则将读取的运算符入OPTR栈,继续读取表达式的下一字符;
    若两个运算符优先级相等,则栈顶运算符直接出栈,继续读取表达式的下一字符;
    若栈顶运算符优先级比较高,则栈顶运算符出栈,同时,OPND栈出两个元素,将运算后的结果放入OPND栈中。

最后,OPND栈中只剩一个元素,即为表达式的值。

代码如下:

#include <iostream>#include <stack>using namespace std;stack<int> OPND;    //操作数stack<char> OPTR;   //操作符int priority[7][7] = {1,1,-1,-1,-1,1,1,1,1,-1,-1,-1,1,1,1,1,1,1,-1,1,1,1,1,1,1,-1,1,1,-1,-1,-1,-1,-1,0,-2,1,1,1,1,-2,1,1,-1,-1,-1,-1,-1,-2,0};    //存储优先级关系void Initial();    //初始化void GetExpressionValue();          //计算表达式的值int GetPriority(char a, char b);    //得到a,b优先级int Operate(int a, char theta, int b);    //计算a theta b的值int main(){    int sum = 0;    Initial();                   //初始化    GetExpressionValue();        //计算表达式的值    cout << OPND.top() << endl;    return 0;}void Initial(){    //初始化,清空两个栈,并将‘#’放入操作符栈中    while(!OPND.empty())    {        OPND.pop();    }    while(!OPTR.empty())    {        OPTR.pop();    }    OPTR.push('#');}void GetExpressionValue(){    int data[12] = {0};    //操作数    int d = 0;    char ch;    char theta;    int a = 0;    int b = 0;    int i = 0;    int j = 0;    cin >> ch;    while(ch != '#' || OPTR.top() != '#')    //两个都=‘#’,求值结束    {        if(isdigit(ch))    //ch是操作数        {            i = 0;            d = 0;            while(isdigit(ch))      //将字符型的操作数转换为整型            {                data[i++] = ch - '0';                cin>>ch;            }            for(j = 0; j < i; j++)            {                d = d + data[j]*pow(10.0, j);            }            OPND.push(d);           //操作数入栈        }        else               //ch是操作符        {            switch(GetPriority(OPTR.top(), ch))            {            case -1:        //栈顶的操作符优先级小于当前操作符                {                    OPTR.push(ch);                    cin>>ch;                    break;                }            case 0:         //相等,消去括号                {                    OPTR.pop();                    cin>>ch;                    break;                }            case 1:         //栈顶的操作符优先级大于当前操作符                {                    theta = OPTR.top();                    OPTR.pop();                    a = OPND.top();                    OPND.pop();                    b = OPND.top();                    OPND.pop();                    OPND.push(Operate(b,theta,a));    //将操作后的结果放入运算数栈中                    break;                }            default:                break;            }        }    }}int GetPriority(char a, char b){    int i = -1;    int j = -1;    switch(a)    {        case '#':            i++;        case ')':            i++;        case '(':            i++;        case '/':            i++;        case '*':            i++;        case '-':            i++;        case '+':            i++;        default:            break;    }    switch(b)    {        case '#':            j++;        case ')':            j++;        case '(':            j++;        case '/':            j++;        case '*':            j++;        case '-':            j++;        case '+':            j++;        default:            break;    }    if(i >= 0 && j >= 0)    {        return priority[i][j];    }    else    {        return -2;    }}int Operate(int a, char theta, int b){    int res = 0;    switch (theta)    {    case '+':        res = a + b;        break;    case '-':        res = a - b;        break;    case '*':        res = a * b;        break;    case '/':        res = a / b;        break;    default:        break;    }    return res;}
2 0