hdu 1237 后缀表达式 栈的应用

这几天在预习数据结构的知识。。刚好看到栈的应用 后缀表达式(逆波兰表达式)。

后缀表达式:操作符都在数字的后面,首先要运用后缀表达式,要明白如何从中缀表达式转换到后缀表达式,然后如何从后缀表达式进行计算。
首先中缀转后缀:

将表达式读入,数字直接输出到后缀表达式中,符号则 判断其与栈顶元素之间优先级的关系,如果优先级不高于栈顶元素的优先级,则将栈顶元素输出,再对新的栈顶元素进行重复操作。直到最后将该符号压入栈中。 如果符号是右括号,将与栈中遇到的第一个左括号之间的符号都输出, 括号都不用输出。

通过后缀表达式进行计算:

将数字都压入另一个存放数字的栈之中,碰到字符就将栈顶元素取出当做第二操作数,弹出,再取一个当做第一操作数,弹出,将计算结果再压入栈中。


第一次写还是写了好久,思路也不能说非常清晰。这道题目我用了‘#’来分隔每个数字与操作符,因为不分隔的话无法判断这是多位的数字还是两个数字。

记录后缀表达式的数组记得要初始化,或者边界不用strlen。

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <stack>
#include <cstring>
#include <cctype>
using namespace std;
#define M 1009
char a[M] = "+-*/";
int b[M] = {1,1,2,2};
char out[M];
char in[M];
stack<char> s; //存放操作符
int main()
{
    while(1)
    {
        //memset(out,'\0',sizeof(out));
        gets(in);
        if(strcmp(in,"0")==0)
            break;
        int k = 0;
        for(int i = 0;i < strlen(in);i++)
        {
            if(in[i]==' ') continue;
            if(isdigit(in[i]))
            {
                if(i < strlen(in)-1 && isdigit(in[i+1]))
                    out[k++] = in[i];
                else
                {
                    out[k++] = in[i];
                    out[k++] = '#';
                }
            }
            else
            {
                while(!s.empty())
                {
                    int p=-1,q=-1;
                    for(int j = 0;j < 4;j++)
                    {
                        if(a[j]==in[i])
                        {
                            p = j;
                        }
                        if(a[j]==s.top())
                        {
                            q = j;
                        }
                    }
                    if(p!=-1 && q!=-1)
                    {
                        if(b[p] <= b[q])
                        {
                            out[k++] = s.top();
                            out[k++] = '#';
                            s.pop();
                        }
                        else break;
                    }
                }
                s.push(in[i]);
            }
        }
        while(!s.empty())
        {
            out[k++] = s.top();
            out[k++] = '#';
            s.pop();
        }
        //printf("%s\n",out);
        //int p = 0;
        double sum = 0;
        stack<double> ss;  //存放数字
        int ok = 0;
        for(int i = 0;i < k;i++)  //循环到后缀表达式的最后一个
        {
            if(isdigit(out[i]))
            {
                sum = 10*sum + out[i]-'0';
                ok = 1;
            }
            else
            {
                if(ok)
                {
                    ss.push(sum);
                    ok = 0;
                    sum = 0;
                }
                if(out[i]!='#')
                {
                    double one ,two;
                    one = ss.top();
                    ss.pop();
                    two = ss.top();
                    ss.pop();
                    double temp;
                    switch (out[i])
                    {
                    case '+':
                        temp = one+two;
                        ss.push(temp);
                        break;
                    case '-':
                        temp = two-one;
                        ss.push(temp);
                        break;
                    case '*':
                        temp = one*two;
                        ss.push(temp);
                        break;
                    case '/':
                        temp = (double)two/one;
                        ss.push(temp);
                        break;
                    }
                }
            }
        }
        if(!ss.empty())
        printf("%.2f\n",ss.top());
        while(!ss.empty()) ss.pop();
        while(!s.empty())s.pop();
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值