中缀表达式转后缀表达式——c语言栈实现

题意

假定运算符集合为{ +、-、*、/、(、)},利用栈将输入的中缀表达式转换成等价的后缀表达式,并输出。

输入格式:

输入一个字符串表示的中缀表达式(以“#”结束),其中每个操作数用一个小写字母表示。

输出格式:

将对应的后缀表达式输出。

输入样例:

a+b-a*((c+d)/e-f)+g#
结尾无空行

输出样例:

ab+acd+e/f-*-g+
结尾无空行

大体思路

所谓后缀表达式,又名逆波兰表达式。
计算机遇见后缀表达式的操作:
从左至右扫描表达式,遇到数字时,将数字压入堆栈,遇到运算符时,弹出栈顶的两个数,用运算符对它们做相应的计算(次顶元素 op 栈顶元素),并将结果入栈;重复上述过程直到表达式最右端,最后运算得出的值即为表达式的结果。
那么如何将中缀转为后缀呢,这里我使用了栈的方法,虚拟了两个栈s1和s2,s1中存储最后的结果,s2为临时栈,用来存储扫描字符串的过程量。
1.扫描输入的字符串。
2.如果遇见的是数字,那么直接压入结果栈s1中。
3.如果遇见的是符号那么就有以下几种结果
3-1 : s2栈为空,直接将符号压入s2栈
3-2 :符号为左括号,直接将符号压入s2栈,如果符号为右括号,那么从s2栈中依次弹出符号压入s1栈,直到遇见左括号,然后销毁一对括号。
3-3:符号为运算符,那么此时应该比较该运算符与s2栈顶运算符的优先级,如果优先级较大那么则压入s2栈中,若优先级较小,那么将s2栈顶运算符压入s1栈中,继续和s2栈道下一个栈顶运算符比较优先级,直到优先级大或者s2栈空,压入s2栈。
4.重复上面的2到3,直到扫描完字符串。
5.由于这里的输入最后是个#号,规定其优先级最低,所以s2栈最后肯定会全部压入s1,如果遇到没有#,那么应该在循环结束后,将s2元素压入s1.

上代码

//
//  main.m
//  PTA
//
//  Created by 差不多先生 on 2021/9/11.
//

// #import <Foundation/Foundation.h>
#include <stdio.h>
#include <string.h>
// 设置符号优先级
int compareReturn(char str1) {
    if (str1 == '#') {
        return 0;
    } else if (str1 == '+' || str1 == '-') {
        return 1;
    } else if (str1 == '*' || str1 == '/') {
        return 2;
    } else if (str1 == '(' || str1 == ')') {
        return 0;
    }
    else {
        // 此时为数字
        return -1;
    }
}
#include <stdio.h>
int main (void) {
    char s1[100];
    int top1 = -1;
    int s2[100];
    char top2 = -1;
    char str[100];
//    char ans;
    printf("请输入中缀表达式\n");
    scanf("%s", str);
    int length = (int)strlen(str);
    for (int i = 0; i < length; ) {
        if (compareReturn(str[i]) == -1) {
            s1[++top1] = str[i++];
        } else if (str[i] == '(') {
            s2[++top2] = str[i++];
        } else if (str[i] == ')') {
            while (compareReturn(s2[top2]) != 0) {
                s1[++top1] = s2[top2--];
            }
            top2--;
            i++;
        } else {
            if (top2 == -1 || compareReturn(s2[top2]) < compareReturn(str[i])) {
                s2[++top2] = str[i++];
            } else {
                s1[++top1] = s2[top2--];
            }
            if (str[i] == '#') {
                break;
            }
        }
    }
//    printf("%d", top2);
    for (int i = 0; i < top1 + 1; i++) {
        printf("%c", s1[i]);
    }
}


这里只考虑了输入的中缀表达式合法,并没有判错代码。
最后推荐一篇博客,里面很全的记载了各种表达式转换的思路:
大牛博客

  • 8
    点赞
  • 71
    收藏
    觉得还不错? 一键收藏
  • 11
    评论
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值