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
    评论
中缀表达式转后缀表达式是一种常用的算法问题。中缀表达式是我们常见的数学表达式形式,例如(3 + 4) * 5 - 6,而后缀表达式(也叫逆波兰表达式)则是将操作符放在操作数之后的表达式形式,例如3 4 + 5 * 6 -。 进行中缀表达式转后缀表达式的算法可以使用栈来实现。具体步骤如下: 1. 创建一个空栈和一个空列表,用于存储操作符和最终的后缀表达式; 2. 从左到右遍历中缀表达式的每个字符; 3. 如果当前字符是数字或字母,则将其添加到后缀表达式的列表中; 4. 如果当前字符是左括号,则将其压入栈中; 5. 如果当前字符是右括号,则将栈中的操作符依次弹出并添加到后缀表达式的列表中,直到遇到左括号为止; 6. 如果当前字符是操作符,则判断栈顶操作符的优先级,如果栈顶操作符的优先级高于等于当前操作符,则将栈顶操作符弹出并添加到后缀表达式的列表中,重复这一步骤直到栈顶操作符的优先级低于当前操作符或栈为空,最后将当前操作符压入栈中; 7. 遍历完中缀表达式后,将栈中的操作符依次弹出并添加到后缀表达式的列表中; 8. 最终得到的列表即为转换后的后缀表达式。 以中缀表达式(3 + 4) * 5 - 6为例,按照上述算法进行转换得到后缀表达式3 4 + 5 * 6 -。 通过这个算法,我们可以将中缀表达式转换为后缀表达式,这种形式更适合计算机进行解析和计算。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值