后缀表达式

一、符号定义

  • RPN:逆波兰式,即后缀表达式
  • e:后缀表达式栈
  • op:操作符栈
  • a:结果栈

二、中缀表达式转换为后缀表达式

  • 如果是操作数就压入栈e
  • 如果是右括号就将栈op中的操作符压入栈e,直到遇到左括号
  • 如果是其他操作符就判断优先级,优先级大的压入栈op,优先级小的弹出栈op并压入栈e(考虑顺序和符号优先级)
void RPN()
{
     
    int i = 0,j = 0,k = 0;
    while(s[i]) {
     
        if(s[i] >= '0' && s[i] <= '9') {
      // 如果是操作数就直接压入栈 
            e[k++] = s[i];
            if(s[i+1] < '0' || s[i+1] > '9') e[k++] = '#';
        } else if(s[i] == ')') {
      // 如果是右括号就将op中的数压入e,直到遇到左括号 
            while(op[--j] != '(') e[k++] = op[j]; 
        } else {
      // 如果是操作符就判断优先级,优先级大压栈,优先级小弹栈,考虑顺序和符号优先级
            if(j > 0) {
     
                if(s[i] == '+' || s[i] == '-') {
     
                    if(op[j-1] != '(') e[k++] = op[--j];
                } else if(s[i] == '*' || s[i] == '/') {
     
                    if(op[j-1] == '*' || op[j-1] == '/') e[k++] = op[--j];
                }
            }
            op[j++] = s[i];
        }
        i++;
    }    
    while(j) e[k++] = op[--j];
    e[k] = '\0';
}

三、后缀表达式计算步骤

  • 如果是操作数就压入栈a
  • 如果是操作符就将两个操作数弹出栈a,计算完后将值压入栈a
int operate(int x,int y,char z) 
{
     
    switch(z) {
     
        case '+': return x + y;
        case '-': return x - y;
        case '*': return x * y;
        default: return x / y;
    }
}
int cal()
{
     
    int x = 0,i = 0,j = 0;
    while(e[i]) {
     
        if(e[i] >= '0' && e[i] <= '9') x = x * 10 + (e[i] - '0');
        else if(e[i] == '#') {
     
            a[j++] = x; // 如果是操作数就压入栈中
            x = 0;
        } else {
     
            a[j-2] = operate(a[j-2],a[j-1],e[i]); // 如果是操作符就将两个操作数弹出栈,计算完后将值压入栈
            j--;
            x = 0;
        }
        i++;
    }
    return a[0];
}

四、完整代码

#include
using namespace std;
const int N = 200;
char s[N],e[N],op[N];
int a[N];
void RPN()
{
     
    int i = 0,j = 0,k = 0;
    while(s[i]) {
     
        if(s[i] >= '0' && s[i] <= '9') {
      // 如果是操作数就直接压入栈 
            e[k++] = s[i];
            if(s[i+1] < '0' || s[i+1] > '9') e[k++] = '#';
        } else if(s[i] == ')') {
      // 如果是右括号就将op中的数压入e,直到遇到左括号 
            while(op[--j] != '(') e[k++] = op[j]; 
        } else {
      // 如果是操作符就判断优先级,优先级大压栈,优先级小弹栈,考虑顺序和符号优先级
            if(j > 0) {
     
                if(s[i] == '+' || s[i] == '-') {
     
                    if(op[j-1] != '(') e[k++] = op[--j];
                } else if(s[i] == '*' || s[i] == '/') {
     
                    if(op[j-1] == '*' || op[j-1] == '/') e[k++] = op[--j];
                }
            }
            op[j++] = s[i];
        }
        i++;
    }    
    while(j) e[k++] = op[--j];
    e[k] = '\0';
}
int operate(int x,int y,char z) 
{
     
    switch(z) {
     
        case '+': return x + y;
        case '-': return x - y;
        case '*': return x * y;
        default: return x / y;
    }
}
int cal()
{
     
    int x = 0,i = 0,j = 0;
    while(e[i]) {
     
        if(e[i] >= '0' && e[i] <= '9') x = x * 10 + (e[i] - '0');
        else if(e[i] == '#') {
     
            a[j++] = x; // 如果是操作数就压入栈中
            x = 0;
        } else {
     
            a[j-2] = operate(a[j-2],a[j-1],e[i]); // 如果是操作符就将两个操作数弹出栈,计算完后将值压入栈
            j--;
            x = 0;
        }
        i++;
    }
    return a[0];
}
int main()
{
     
    cin >> s;
    RPN();
    int ans = cal();
    cout << ans << endl;
    return 0;
}

你可能感兴趣的:(算法)