数据结构期末编程题热身——栈的应用,中缀表达式转为后缀表达式再求值

中缀表达式转为后缀表达式需要用到栈

后缀表达式再求值也要用到栈

1.中缀&后缀表达式

 2.后缀表达式求值

2.1需要用到栈的结构:

  1. 从左往右读表达式,读到运算量就入栈,
  2. 读到运算符的话,就从栈中弹出前面刚刚读过的两个运算量参与运算,结果是一个新的运算量,将他压入栈中。
  3. 处理完整个后缀表达式之后,栈顶元素就是结果值

2.2举例

过程详述(拿纸自己跟着画一下):

  1. 从左向右读,读到6入栈,读到2入栈
  2. 读到 /,把6和2取出来,进行6/2,得到3入栈,(现在栈里面有一个3)
  3. 继续读,又读到3,3入栈(现在栈里面有2个3)
  4. 读到 -,那么3-3=0,0入栈
  5. 读到4,4入栈,读到2,2入栈(现在栈里面有0,4,2)
  6. 读到* ,取出4,2,进行4*2=8,8入栈(现在栈里面有0,8)
  7. 读到 +,取出0,8,0+8=8,8入栈
  8. 结束,栈里面只有一个元素,8,就是最终答案

 3.代码展示

首先给你一个中缀表达式,

3.1先转化为后缀表达式

我们用transplate函数实现此功能,有详细注释

记住str2中各个量之间是要有空格的,可以思考:中缀表达式中数字之间是有符号的:19+5意思就很明确,但是后缀表达式中195+什么意思呢,是19+5还是1+95呢,对吧,所以str2存储的时候应该是19 5 +,中间有空格!

详细步骤如下:

  1. 循环遍历str1
  2. 遇到数字就直接写到str2里面
  3. 遇到运算符号就比较它和栈顶元素的优先级高低(symcmp),决定是否入栈
#include<stdio.h>
#define MAXSIZE 100
int symcmp(char a,char b)
{
    if(b=='(')
    return 1;
    else if((b=='*'||b=='/')&&(a=='-'||a=='('||a=='+'))
                return 1;
    else if((b=='+'||b=='-')&&(a=='('))
                return 1;
    else
        return 0;

}

void transplant(char *str1,char *str2)
{//str1是中缀表达式,str2是目标生成的后缀表达式
    char stack[MAXSIZE];//数组模拟栈
    int top=-1;
    int j=0;
    for(int i=0;str1[i]!='\0';i++)//开始遍历str
    {
        if(str1[i]>='0'&&str1[i]<='9')
            str2[j++]=str1[i];//如果是0到9之间的数字,就直接赋值给str2
        else
        {//遇到各种符号了
            if(i!=0&&str2[j-1]!=' ')
                str2[j++]=' ';//需要加上一个空格做分割
            if(str1[i]==')')//一直输出,直到(出栈,但是不输出
            {
                while(stack[top]!='(')
                {
                    str2[j++]=stack[top--];
                    str2[j++]=' ';
                }
                top--;//相当于(出去了
            }
            else if(symcmp(stack[top],str1[i])==0)//str1[i]运算符优先级低或相等,则stack出栈
            {
                while(top>-1&&(symcmp(stack[top],str1[i])==0))//要么栈为空、要么str[i]优先级为高,则停止出栈
                //也就是说,要是你一直满足str1[i]运算符优先级低或相等,那你就一直出栈吧
                    {
                        str2[j++]=stack[top--];
                        str2[j++]=' ';
                    }
                    stack[++top]=str1[i];//该出栈的都出去了,把str[i]放进来
            }
            else//str1[i]运算符优先级高,或者等于‘(’,则str[i]入栈
            {
                stack[++top]=str1[i];
            }

        }
    }
    if(str2[j-1]!=' ')
        str2[j++]=' ';
    while(top>-1)//栈里边还剩下的符号都出来吧!
    {
        str2[j++]=stack[top--];
        str2[j++]=' ';
    }
    str2[j-1]='\0';//以'\0'结尾
    printf("%s",str2);

}

3.2后缀表达式求值(用到栈结构)

int cal(char *str)
{
    int stack[MAXSIZE];
    int top=-1,tmp=0,k=10;
    for(int i=0;str[i]!='\0';i++)
    {
        if(str[i]>='0'&&str[i]<='9')
        {
            tmp=tmp*10+str[i]-'0';
        }
        else if(str[i]==' ')
        {
            stack[++top]=tmp;
            tmp=0;
        }
        else
        {
            switch(str[i])
            {
                case '+':tmp=stack[top-1]+stack[top];break;
                case '-':tmp=stack[top-1]-stack[top];break;
                case '*':tmp=stack[top-1]*stack[top];break;
                case '/':tmp=stack[top-1]/stack[top];break;

            }
            top-=2;
        }
    }
    stack[++top]=tmp;
    return stack[0];
}

4.总体代码:可复制直接运行,已设好初始用例!

#include<stdio.h>
#define MAXSIZE 100
int symcmp(char a,char b)
{
    if(b=='(')
    return 1;
    else if((b=='*'||b=='/')&&(a=='-'||a=='('||a=='+'))
                return 1;
    else if((b=='+'||b=='-')&&(a=='('))
                return 1;
    else
        return 0;

}

void transplant(char *str1,char *str2)
{//str1是中缀表达式,str2是目标生成的后缀表达式
    char stack[MAXSIZE];//数组模拟栈
    int top=-1;
    int j=0;
    for(int i=0;str1[i]!='\0';i++)//开始遍历str
    {
        if(str1[i]>='0'&&str1[i]<='9')
            str2[j++]=str1[i];//如果是0到9之间的数字,就直接赋值给str2
        else
        {//遇到各种符号了
            if(i!=0&&str2[j-1]!=' ')
                str2[j++]=' ';//需要加上一个空格做分割
            if(str1[i]==')')//一直输出,直到(出栈,但是不输出
            {
                while(stack[top]!='(')
                {
                    str2[j++]=stack[top--];
                    str2[j++]=' ';
                }
                top--;//相当于(出去了
            }
            else if(symcmp(stack[top],str1[i])==0)//str1[i]运算符优先级低或相等,则stack出栈
            {
                while(top>-1&&(symcmp(stack[top],str1[i])==0))//要么栈为空、要么str[i]优先级为高,则停止出栈
                //也就是说,要是你一直满足str1[i]运算符优先级低或相等,那你就一直出栈吧
                    {
                        str2[j++]=stack[top--];
                        str2[j++]=' ';
                    }
                    stack[++top]=str1[i];//该出栈的都出去了,把str[i]放进来
            }
            else//str1[i]运算符优先级高,或者等于‘(’,则str[i]入栈
            {
                stack[++top]=str1[i];
            }

        }
    }
    if(str2[j-1]!=' ')
        str2[j++]=' ';
    while(top>-1)//栈里边还剩下的符号都出来吧!
    {
        str2[j++]=stack[top--];
        str2[j++]=' ';
    }
    str2[j-1]='\0';//以'\0'结尾
    printf("%s",str2);

}

int cal(char *str)
{
    int stack[MAXSIZE];
    int top=-1,tmp=0,k=10;
    for(int i=0;str[i]!='\0';i++)
    {
        if(str[i]>='0'&&str[i]<='9')
        {
            tmp=tmp*10+str[i]-'0';
        }
        else if(str[i]==' ')
        {
            stack[++top]=tmp;
            tmp=0;
        }
        else
        {
            switch(str[i])
            {
                case '+':tmp=stack[top-1]+stack[top];break;
                case '-':tmp=stack[top-1]-stack[top];break;
                case '*':tmp=stack[top-1]*stack[top];break;
                case '/':tmp=stack[top-1]/stack[top];break;

            }
            top-=2;
        }
    }
    stack[++top]=tmp;
    return stack[0];
}
int main()
{
 	char *str = "50+7*2*(2+1-1-1)-3";
 	char s[MAXSIZE];
 	transplant(str,s);
    int res=cal(s);
    printf("\n%d",res);
    return 0;
}

  • 11
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

.别止步春天.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值