中缀表达式的值

由于不想循规蹈矩…所以,不想转后缀再求后缀表达式的值,所以就直接利用中缀表达式和两个栈进行求值,一个栈放数字,另一个栈放操作符.调试的时候稍微遇到了些瓶颈,不过大体来说还是比较顺利的.就是要注意栈非空,栈里只有一个左括号等条件的判定.

中缀表达式的值

总时间限制: 200ms 内存限制: 1024kB

描述

人们熟悉的四则运算表达式称为中缀表达式,例如(23+34*45/(5+6+7))。在程序设计语言中,可以利用堆栈的方法把中缀表达式转换成保值的后缀表达式(又称逆波兰表示法),并最终变为计算机可以直接执行的指令,得到表达式的值。

给定一个中缀表达式,编写程序,利用堆栈的方法,计算表达式的值。

输入
第一行为测试数据的组数N
接下来的N行,每行是一个中缀表达式。表达式中只含数字、四则运算符和圆括号,操作数都是正整数,数和运算符、括号之间没有空格。中缀表达式的字符串长度不超过600。

输出
对每一组测试数据输出一行,为表达式的值

样例输入
3
3+5*8
(3+5)*8
(23+34*45/(5+6+7))
样例输出
43
64
108
#include <iostream>
#include <iomanip>
#include <string>
#include <string.h>
#include <stdio.h>
#include <stack>
using namespace std;

int n, len, word_len,temp;
char des[700], word[100];

stack<int> number;
stack<char> symbol;

int pri(char a,char b)
{
    if(b=='*' || b=='/')
    {
        if(a=='*' || a=='/')
            return 0;
        else
            return -1;//a比b优先级低
    }
    else
    {

        if(a=='*' || a=='/')
            return 1;
        else
            return 0;
    }
}
void cal(char c,int t1,int t2)
{
    switch(c)
    {
        case '+':{
            number.push(t1+t2);
            symbol.pop();
            break;
        }
        case '-':{
            number.push(t2-t1);
            symbol.pop();
            break;
        }
        case '*':{
            number.push(t1*t2);
            symbol.pop();
            break;
        }
        case '/':{
            number.push(t2/t1);
            symbol.pop();
            break;
        }
    }
}

int main()
{
    scanf("%d",&n);
    while(n--)
    {
        scanf("%s",&des);
        len = strlen(des);
        for(int i=0;i<len;i++)
        {
            if(des[i] == '(')
            {
                symbol.push(des[i]);
            }
            else if(des[i]>='0' && des[i]<='9')
            {
                word[word_len++] = des[i];
                if(i+1>=len ||   !(des[i+1]>='0' && des[i+1]<='9'))//数字结束
                {
                    word[word_len] = '\0';
                    temp = atoi(word);
                    word_len = 0;
                    number.push(temp);
                }
            }
            else if(des[i] == ')')
            {
                while(symbol.top() != '(')
                {
                    int t1 = number.top(); number.pop();
                    int t2 = number.top(); number.pop();
                    cal(symbol.top(),t1,t2);
                }
                symbol.pop();//弹出左括号
            }
            else
            {
                if(symbol.empty() || symbol.top()=='(')
                    symbol.push(des[i]);
                else if(pri(des[i],symbol.top()) == 1)
                {
                    symbol.push(des[i]);
                }
                else
                {
                    while(!(symbol.empty()) && symbol.top()!='(' && pri(symbol.top(),des[i])>=0)
                    {
                        int t1 = number.top(); number.pop();
                        int t2 = number.top(); number.pop();
                        cal(symbol.top(),t1,t2);
                    }
                    symbol.push(des[i]);
                }
            }
        }
        while(!symbol.empty())
        {
            int t1 = number.top(); number.pop();
            int t2 = number.top(); number.pop();

            cal(symbol.top(),t1,t2);
        }
        cout<<number.top()<<endl;
        number.pop();
    }
    return 0;
}
  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值