2014.6.2~3逆波兰表达式求值(栈和队列)

说好的每天写一篇刚开始就没坚持下去orz。。羞愧万分!!最近有点忙,刚自学数据结构,练习栈和队列,期末考试也快到了,要想保持第一的位置还是要小小的努力一下的(高数离散你们还爱我的吧!!虽然没怎么搭理你们TT),这学期的C语言程序设计要做一个大程序,之前都没怎么做,最近也在赶工,还有什么程序设计大赛,齐鲁软件大赛。。。小娘我只是一个酱油君。饶了我吧!   以后就三天写一篇博客吧hiahiahiahia~~~:

逆波兰表达式求值(栈和队列)

Description

从键盘上输入一个逆波兰表达式,用伪码写出其求值程序。规定:逆波兰表达式的长度不超过一行,以@符作为输入结束,操作数之间用空格分隔,操作符只可能有+、-、*、/四种运算。例如:

请输入一个以'@'字符结束的中缀算术表达式: 
12+(3*(20/4)-8)*6@ 
对应的后缀算术表达式为: 
12 3 20 4 /*8 -6 *+@ 
求值结果为:54

Input

输入:

12+(3*(20/4)-8)*6@ 

Output

输出:

54

Sample Input

12+(3*(20/4)-8)*6@ 

Sample Output

54
 
 
逆波兰表达式是一种十分有用的表达式,它将复杂表达式转换为可以依靠简单的操作得到计算结果的表达式。例如(a+b)*(c+d)转换为ab+cd+*
它的优势在于只用两种简单操作,入栈和 出栈就可以搞定任何普通表达式的运算。其运算方式如下:
如果当前字符为 变量或者为数字,则压栈,如果是运算符,则将栈顶两个元素弹出作相应运算,结果再入栈,最后当表达式扫描完后,栈里的就是结果。
算法:
一、 将中缀表达式转换成后缀表达式算法:
1、从左至右扫描一中缀表达式。
2、若读取的是操作数,则判断该操作数的类型,并将该操作数存入操作数堆栈
3、若读取的是运算符
(1) 该运算符为左括号"(",则直接存入运算符堆栈。
(2) 该运算符为右括号")",则输出运算符堆栈中的运算符到操作数堆栈,直到遇到左括号为止。
(3) 该运算符为非括号运算符:
(a) 若运算符堆栈栈顶的运算符为括号,则直接存入运算符堆栈。
(b) 若比运算符堆栈栈顶的运算符优先级高或相等,则直接存入运算符堆栈。
(c) 若比运算符堆栈栈顶的运算符优先级低,则输出栈顶运算符到操作数堆栈,并将当前运算符压入运算符堆栈。
4、当表达式读取完成后运算符堆栈中尚有运算符时,则依序取出运算符到操作数堆栈,直到运算符堆栈为空。
二、逆波兰表达式求值算法:
1、循环扫描语法单元的项目。
2、如果扫描的项目是操作数,则将其压入操作数堆栈,并扫描下一个项目。
3、如果扫描的项目是一个二元运算符,则对栈的顶上两个操作数执行该运算。
4、如果扫描的项目是一个一元运算符,则对栈的最顶上操作数执行该运算。
5、将运算结果重新压入堆栈。
6、重复步骤2-5,堆栈中即为结果值。
AC代码:
#include <iostream>
#include <algorithm>
#include<string.h>
#include <cstdio>
#define selemtype int
using namespace std;
struct node
{
    selemtype data;
    struct node *next;
};
struct stack
{
    struct node*top;
};
struct stack * createmptystack()
{
    struct stack *s;
    s=(struct stack *)malloc(sizeof(struct stack));
    if(s!=NULL)
    {
        s->top=NULL;
    }
    return s;
}
int stackempty(struct stack *s)
{
    return s->top==NULL;
}
int push(struct stack *s,selemtype x)
{
    struct node * pnew;
    pnew=(struct node *)malloc(sizeof(struct node));
    if(pnew!=NULL)
    {
        pnew->data=x;
        pnew->next=s->top;
        s->top=pnew;
        return 1;
    }
    return 0;
}
selemtype pop(struct stack *s)
{
    selemtype x;
    struct node *ptemp;
    x=s->top->data;
    ptemp=s->top;
    s->top=s->top->next;
    free(ptemp);
    return x;
}
selemtype gettop(struct stack *s)
{
    return s->top->data;
}
int priority(int m,int s)
{
    int i;
    int a[2],b[2];
    a[0]=m;
    a[1]=s;
    for(i=0;i<2;i++)
    {
        if(a[i]=='(')
            b[i]=0;
        else if(a[i]=='+'||a[i]=='-')
            b[i]=1;
        else if(a[i]=='*'||a[i]=='/')
            b[i]=2;
    }
    if(b[0]-b[1]>=0)
        return 1;
    else
        return 0;
}
void trans(char *s1)
{
    char s2[1000];
    struct stack * s;
    s=createmptystack();
    int i=0,j=0,m;
    push(s,'(');
    while(s1[i]!='@')
    {
        if(s1[i]>='0'&&s1[i]<='9')
        {
            s2[j++]=s1[i];
            if(s1[i+1]<'0'||s1[i+1]>'9')
                s2[j++]=' ';
        }
        else if(s1[i]=='(')
            push(s,s1[i]);
        else if(s1[i]==')')
        {
            m=gettop(s);
            while(m!='(')
            {
                m=pop(s);
                s2[j++]=m;
                m=gettop(s);
            }
            m=pop(s);
        }
        else
        {
            m=gettop(s);
            while(priority(m,s1[i]))
            {
                m=pop(s);
                s2[j++]=m;
                m=gettop(s);
            }
            push(s,s1[i]);
        }
        i++;
    }
    m=gettop(s);
    while(m!='(')
    {
        m=pop(s);
        s2[j++]=m;
        m=gettop(s);
    }
    s2[j]='@';
    for(i=0; s2[i]!='@'; i++)
    {
        s1[i]=s2[i];
    }
    s1[i]='@';
}
int cal(char * s1)
{
    int m,x,y,z,i=0;
    struct stack *s;
    s=createmptystack();
    while(s1[i]!='@')
    {
        if(s1[i]>='0'&&s1[i]<='9')
        {
            m=0;
            while(s1[i]!=' ')
            {
                m=m*10+(s1[i]-'0');
                i++;
            }
            push(s,m);
            i++;
        }
        else
        {
            y=pop(s);
            x=pop(s);
            if(s1[i]=='+')
                z=x+y;
            else if(s1[i]=='-')
                z=x-y;
            else if(s1[i]=='*')
                z=x*y;
            else if(s1[i]=='/')
                z=x/y;
            push(s,z);
            i++;
        }
    }
    return gettop(s);
}
int main()
{
    char s1[1000];
    int i=0;
    s1[i]=getchar();
    while(s1[i]!='@')
    {
        i++;
        scanf("%c",&s1[i]);
    }
    trans(s1);
    printf("%d",cal(s1));
    return 0;
}
For Our Fates Edge Of Tomorrow.Fighting for ...
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值