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

来源:互联网 发布:模拟退火算法实例c 编辑:程序博客网 时间:2024/05/09 19:34

说好的每天写一篇刚开始就没坚持下去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 intusing 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 ...
0 0
原创粉丝点击