前缀表达式(波兰表达式)转 后缀表达式(逆波兰表达式)(java实现)

本文详细介绍了如何将中缀表达式转换为后缀表达式,包括转换思路、关键步骤的图片演示及完整的Java代码实现。通过遍历中缀表达式,使用栈来处理运算符,遵循运算符优先级规则,最终得到无括号的后缀表达式,方便计算机进行计算。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


前言

前缀表达式:就是我们常见的算术表达式,这里就以1+((2+3))*5)-5举例。
后缀表达式:上面式子对应的后缀表达式为 1 2 3 + 5 * + 5 - 不难看出后缀表达式没有括号,而真因后缀表达式的这个形式,很好的贴合了计算机底层的运算原理(栈)


一、转换思路

1、初始化一个队列suffixList(用于存放最终的后缀表达式), 初始化一个栈stringStack(用于存放运算符)
2、从左至右遍历中缀表达式
3、遇到运算数,压入suffixList中
4、遇到运算符,压入stringStack中
   1)若stringStack栈为空,或stringStack栈顶元素为“(”,则直接压入stringStack栈
   2)否则,若运算符优先级高于栈顶元素,直接压入栈
   3)否则,将stringStack栈顶元素弹出,压入到suffixList中,回到第4步重新比较
5、遇到括号“(”或“)”
   1)若为“(”,则直接压入stringStack栈
   2)若为“)”,则依次弹出stringStack中的运算符,压入suffixList中,直到遇到“(”为止,然后移除“(”         注意:这里是直接在stringStack中移除“(”!
6、遍历完毕后,将stringStack中剩余的元素依次弹出并压入到suffixList中,遍历输出队列suffixList即为算数表达式对应的后缀表达式(逆波兰表达式)

二、图片演示

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述在这里插入图片描述
在这里插入图片描述在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

三、代码实现

1、核心代码

代码如下(示例):

  //将中缀表达式转化为后缀表达式
    public static List<String> parseSuffixExpressionList(List<String> infixList) {
       // Stack<String> numberStack = new Stack<>(); //存放需计算的数字 (在整个过程中一直在进栈, 最终也是将这个栈放到一个ArrayList中 故可直接新建一个List 如下
        ArrayList<String> suffixList = new ArrayList<>();
        Stack<String> stringStack = new Stack<>(); //存放运算符号

        for (String s : infixList) {
            if (s.matches("\\d+")) { //正则表达式 匹配到是多位数
                suffixList.add(s);
            } else if (s.equals("(")) {
                stringStack.push(s);
            } else if (s.equals(")")) {
                while (!stringStack.peek().equals("(")) { //peek() 方法 查看栈顶元素 但不移除
                    suffixList.add(stringStack.pop()); //符号栈中弹出运算符加到list中 直到遇到符号(
                }
                stringStack.pop(); //将”(“ 弹出  消除括号
            } else {
                //当s的优先级小于stringStack栈顶的优先级 将stringStack栈顶的元素弹出并加入到suffixList中
                if (stringStack.size() > 0 && Operation.getValue(stringStack.peek()) >= Operation.getValue(s)) {
                    suffixList.add(stringStack.pop());
                }
                stringStack.push(s); //将s压入栈
            }
        }

        //将stringStack中剩余的运算符一次弹出并加入到suffixList中
        while (stringStack.size() != 0) {
            suffixList.add(stringStack.pop());
        }
        return suffixList; //放到List中 即为顺序输出 (若开始时创建的是两条栈,  则最终应该反转)
    }

2.完整代码

代码如下(示例):

package com.xx.stack;

import java.util.ArrayList;
import java.util.List;
import java.util.Stack;

/**
 * @author 谢鑫
 * @version 1.0
 */
public class InfixToSuffix {
    public static void main(String[] args) {
        String infixExpression = "1 + ( ( 2 + 3 ) * 5 ) - 5";
        List<String> infixList = getListString(infixExpression); //将中缀表达式放到list中
        System.out.println("中缀表达式对应的List");
        System.out.println(infixList);


        System.out.println("后缀表达式对应的List");
        List<String> suffixList = parseSuffixExpressionList(infixList);
        System.out.println(suffixList);

    }

    //将中缀表达式放到ArrayList中
    public static List<String> getListString(String infixExpression) {
        //将suffixExpression分割
        String[] split = infixExpression.split(" ");
        List<String> list = new ArrayList<>();
        for (String element : split) { ;
            list.add(element);
        }
        return list;
    }


    //将中缀表达式转化为后缀表达式
    public static List<String> parseSuffixExpressionList(List<String> infixList) {
       // Stack<String> numberStack = new Stack<>(); //存放需计算的数字 (在整个过程中一直在进栈, 最终也是将这个栈放到一个ArrayList中 故可直接新建一个List 如下
        ArrayList<String> suffixList = new ArrayList<>();
        Stack<String> stringStack = new Stack<>(); //存放运算符号

        for (String s : infixList) {
            if (s.matches("\\d+")) { //正则表达式 匹配到是多位数
                suffixList.add(s);
            } else if (s.equals("(")) {
                stringStack.push(s);
            } else if (s.equals(")")) {
                while (!stringStack.peek().equals("(")) { //peek() 方法 查看栈顶元素 但不移除
                    suffixList.add(stringStack.pop()); //符号栈中弹出运算符加到list中 直到遇到符号(
                }
                stringStack.pop(); //将”(“ 弹出  消除括号
            } else {
                //当s的优先级小于stringStack栈顶的优先级 将stringStack栈顶的元素弹出并加入到suffixList中
                if (stringStack.size() > 0 && Operation.getValue(stringStack.peek()) >= Operation.getValue(s)) {
                    suffixList.add(stringStack.pop());
                }
                stringStack.push(s); //将s压入栈
            }
        }

        //将stringStack中剩余的运算符一次弹出并加入到suffixList中
        while (stringStack.size() != 0) {
            suffixList.add(stringStack.pop());
        }
        return suffixList; //放到List中 即为顺序输出 (若开始时创建的是两条栈,  则最终应该反转)
    }
}

class                               Operation {
    private static int ADD = 1;
    private static int SUB = 1;
    private static int MUL = 2;
    private static int DIV = 2;

    public static  int getValue(String operation) {
        int result = 0;
        switch (operation) {
            case "+":
                result = ADD;
                break;
            case "-":
                result = SUB;
                break;
            case "*":
                result = MUL;
                break;
            case "/":
                result = DIV;
                break;
            default:
                System.out.println("出发处理该运算符!");
                break;
        }
        return result;
    }
}


总结

望纠正!

在C语言中,将前缀表达式换为后缀表达式(也称逆波兰表示法)通常使用数据结构。以下是一个简单的过程和伪代码描述: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> // 定义结构体 typedef struct { int* elements; int top; int size; } Stack; // 初始化 Stack* create_stack(int capacity) { Stack* s = malloc(sizeof(Stack)); s->elements = (int*)malloc(capacity * sizeof(int)); s->top = -1; s->size = 0; return s; } // 入操作 void push(Stack* s, int value) { if (s->top == s->size - 1) { s->size *= 2; s->elements = realloc(s->elements, s->size * sizeof(int)); } s->elements[++s->top] = value; } // 出操作 int pop(Stack* s) { return s->elements[s->top--]; } // 判断是否为空 int is_empty(Stack* s) { return s->top == -1; } // 前缀后缀函数 char* prefix_to_postfix(char* expression) { Stack* stack = create_stack(strlen(expression) + 1); char* result = malloc(strlen(expression) * 2 + 1); // 结果字符串的长度包括空格和'\0' int i = 0, j = 0; while (expression[i]) { if (isdigit(expression[i])) { // 如果是数字,直接添加到结果 result[j++] = expression[i++]; } else { if (!is_empty(stack)) { // 当不为空,出操作直到找到该运算符的左括号或遇到其他优先级更高的运算符 while (!is_empty(stack) && !isdigit(stack->elements[stack->top]) && (expression[i] != ')' || stack->elements[stack->top] != '(')) { result[j++] = stack->elements[stack->top--]; } } push(stack, expression[i++]); // 将当前运算符压入 } } // 添加剩余的顶元素到结果 while (!is_empty(stack)) { result[j++] = stack->elements[stack->top--]; } result[j] = '\0'; free(stack->elements); free(stack); return result; } int main() { char* prefix_expr = "2+3*4"; char* postfix_expr = prefix_to_postfix(prefix_expr); printf("Prefix: %s\nPostfix: %s", prefix_expr, postfix_expr); free(postfix_expr); return 0; } ``` 注意,此代码仅作为示例,实际应用中需要考虑错误处理和边界条件。运行时,你可以用上述代码替换到C项目中测试不同的前缀表达式
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值