C语言中缀表达式转后缀表达式

一.基本概念:

逆波兰式(Reverse Polish notation,RPN,或逆波兰记法),也叫后缀表达式(将运算符写在操作数之后)。

将中缀表达式转化为后缀表达式的原因:

原因就在于这个简单是相对人类的思维结构来说的,对计算机而言中序表达式是非常复杂的结构。相对的,逆波兰式在计算机看来却是比较简单易懂的结构。因为计算机普遍采用的内存结构是栈式结构,它执行先进后出的顺序。

二.算法思路:

首先设置一个操作符栈,临时存放操作符,再设置一个队列或数组,存放后缀式。#作为运算开始和结束的标志。

  • 1、从左到右扫描中缀式,若碰到操作数,则把操作数加入后缀式中。

  • 2、如果碰到操作符,就将其优先级与操作符栈的栈顶操作符比较。

    a. 若碰到左括号,则压入操作符栈

    b. 若碰到右括号,则将操作符栈内的元素依次移入到后缀式中,直到左括号停止(括号中依然遵循c,d两条)。

    c. 若操作符的优先级高于栈顶操作符,则压入操作符栈

    d. 若操作符的优先级等于或低于栈顶操作符,则将栈顶操作符移入到后缀式中,接着与操作符栈的下一个操作符比较,直到操作符高于,再将操作符压入到操作符栈中 。

123

三.代码演示:

输入样例:

a+b-a*((c+d)/e-f)+g#

输出样例:

ab+acd+e/f-*-g+

#include <stdio.h>
#include <string.h>

int Compare(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; //字母或者数字 
    }
}

int main (void) {
	//结果栈 
    char endStack[100];
    int endTop = -1;
    
    //操作符栈 
    char symbolStack[100];
    int symbolTop = -1;
    
    char str[100];
    scanf("%s", str);
    int length = (int)strlen(str);
    
    for (int i = 0; i < length; ) {
        if (Compare(str[i]) == -1) {    //是字母或者数字就把它压入结果栈中 
            endStack[++endTop] = str[i++];
        } else if (str[i] == '(') {     //遇到(直接压入操作符栈中 
            symbolStack[++symbolTop] = str[i++];
        } else if (str[i] == ')') {     //遇到)将操作符栈中的符号全部弹出压入结果栈中 
            while (Compare(symbolStack[symbolTop]) != 0) {
                endStack[++endTop] = symbolStack[symbolTop--];
            }
            symbolTop--;
            i++;
        } else {     //遇到操作符 
            if (symbolTop == -1 || Compare(symbolStack[symbolTop]) < Compare(str[i])) { //操作符栈为空或者字符串中的操作符优先级大于操作符栈顶操作符的优先级就将该操作符压入操作符栈中 
                symbolStack[++symbolTop] = str[i++];
            } else {     //若字符串中的操作符优先级小于或等于操作符栈顶操作符的优先级,就将操作符栈的栈顶元素弹出压入结果栈中,并且字符串中的位置不变,直到操作符栈为空或遇到高优先级的操作符 
                endStack[++endTop] = symbolStack[symbolTop--];
            }
            if (str[i] == '#') {
                break;
            }
        }
    }
    for (int i = 0; i < endTop + 1; i++) {
        printf("%c", endStack[i]);
    }
    return 0;
}    

543

  • 15
    点赞
  • 109
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值