中缀表达式转前缀表达式的java代码实现(思路在代码注释中,由于减号和符号无法区分 故所有减法作负数加法计算)

30 篇文章 0 订阅
22 篇文章 0 订阅

工具类(包含表达式切割方法,和实现方法)

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

/**
 * className:Util
 *
 * @author:zjl
 * @version:0.1
 * @date:2020/8/419:53
 * @since:jdk1.8
 */
public class Util {
    /**
     * 分割表达式
     * @param expression
     * @return
     */
    public static List<String> splitExpression(String expression){
        char[] chars = expression.toCharArray();
        List<String> listString = new ArrayList<>();
        for (int i = 0; i < chars.length; i++) {
            if(Character.isDigit(chars[i])||chars[i]=='.'|| chars[i]=='-'){
                StringBuilder builder = new StringBuilder();
                while (true){
                    builder.append(chars[i]);
                    if((i==chars.length-1||!Character.isDigit(chars[i+1])&&chars[i+1]!='.'))
                        break;
                    i++;
                }
                listString.add(builder+"");
            }else {
                listString.add(String.valueOf(chars[i]));
            }
        }
        return listString;
    }

    public static int getPriority(String symbol){
        switch (symbol){
            case "+" :
                return 1;
//            case "-" :
//                return 1;
            case "*" :
                return 2;
            case "/" :
                return 2;

        }
        return -1;
    }
//    1初始化两个栈:运算符栈stackSym和储存中间结果的栈stackNum;
//    2从右至左扫描中缀表达式;
//    3遇到操作数时,将其压stackNum;
//    4遇到运算符时,比较其与s1栈顶运算符的优先级:
//        1)如果s1为空,或栈顶运算符为左括号“)”,则直接将此运算符入栈;
//        2)否则,若优先级比栈顶运算符的高或者相等,也将运算符压入stackSym;
//        3)否则,将s1栈顶的运算符弹出并压入到stackNum中,再次转到(4-1)与stackSym中新的栈顶运算符相比较;
//
//    5遇到括号时:
//            (1) 如果是左括号“)”,则直接压入stackSym
//            (2)如果是右括号“(”,则依次弹出stackSym栈顶的运算符,并压入stackNum,直到遇到左括号为止,此时将这一对括号丢弃
//    6重复步骤2至5,直到表达式的最右边
//    7将stackSym中剩余的运算符依次弹出并压入stackNum
//    8依次弹出stackNum中的元素并输出,结果即为中缀表达式对应的后缀表达式
        public static String cenTranBac(String expression){
            Stack<String> stackNum = new Stack<>();
            Stack<String> stackSym = new Stack<>();
            List<String> list = splitExpression(expression);
            Pattern pattern = Pattern.compile("[1-9]\\d*.\\d*|[1-9]|0.\\d*[1-9]\\d*");
            Pattern pattern0 = Pattern.compile("-([1-9]\\d*.\\d*||[1-9]0.\\d*[1-9]\\d*)");
            for (int i = list.size()-1; i >= 0; i--) {
                if(!pattern.matcher(list.get(i)).matches()&&!pattern0.matcher(list.get(i)).matches()){
                    if(stackSym.empty()||list.get(i).equals(")")||stackSym.peek().equals(")")){
                        stackSym.push(list.get(i));
                    }else if(list.get(i).equals("(")){
                        while (!stackSym.peek().equals(")")){
                            String pop = stackSym.pop();
                            stackNum.push(pop);
                        }
                        stackSym.pop();
                    } else{
                        if(getPriority(list.get(i))>=getPriority(stackSym.peek())){
                            stackSym.push(list.get(i));
                        }else {
                             while (getPriority(list.get(i))<getPriority(stackSym.peek())){
                                 stackNum.push(stackSym.pop());
                                 if(stackSym.empty()||stackSym.peek().equals(")"))
                                     break;
                             }
                             stackSym.push(list.get(i));
                        }
                    }
                }else {
                    stackNum.push(list.get(i));
                }
            }
            while (!stackSym.empty()){
                stackNum.push(stackSym.pop());
            }
//            while (!stackNum.empty()){
//                stackSym.push(stackNum.pop());
//            }
            StringBuilder bacExpression = new StringBuilder();
            while (!stackNum.empty()){
                bacExpression.append(stackNum.pop()+" ");
            }

            return bacExpression+"";
        }



}

测试类

import java.util.List;

/**
 * className:Test
 *
 * @author:zjl
 * @version:0.1
 * @date:2020/8/420:04
 * @since:jdk1.8
 */
public class Test {

    public static void main(String[] args) {
        //分割表达测试
        List<String> list = Util.splitExpression("3*(4+2)+8.0/-2");
        System.out.println("=============================================");
        System.out.print("3*(4+2)+8.0/-2 " + "分割后的结果:");
        list.forEach(p -> {
            System.out.print(p + ",");
        });
        System.out.println();
        System.out.println("=============================================");
        //中缀转前缀
        String s = Util.cenTranBac("3*(4+2)+8.0/2");
        System.out.println("3*(4+2)+8.0/2 转为前缀式:" + s);
        System.out.println("=============================================");

        String s0 = Util.cenTranBac("1+(2+3)*4+5");
        System.out.println("1+(2+3)*4+5 转为前缀式:" + s0);
        System.out.println("=============================================");

    }

}

测试结果
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是使用Qt实现中缀表达式前缀表达式代码: ```cpp #include <QStack> #include <QString> QString infixToPrefix(QString infix) { QStack<QChar> operators; QStack<QString> operands; for(int i = 0; i < infix.length(); i++) { QChar c = infix[i]; if(c == ' ' || c == '\t') { continue; } else if(c.isDigit() || c.isLetter()) { QString operand; while(i < infix.length() && (infix[i].isDigit() || infix[i].isLetter())) { operand.append(infix[i++]); } operands.push(operand); i--; } else if(c == ')') { operators.push(c); } else if(c == '(') { while(!operators.isEmpty() && operators.top() != ')') { QString rightOperand = operands.pop(); QString leftOperand = operands.pop(); QChar op = operators.pop(); QString expression = op + leftOperand + rightOperand; operands.push(expression); } operators.pop(); } else { while(!operators.isEmpty() && precedence(c) <= precedence(operators.top())) { QString rightOperand = operands.pop(); QString leftOperand = operands.pop(); QChar op = operators.pop(); QString expression = op + leftOperand + rightOperand; operands.push(expression); } operators.push(c); } } while(!operators.isEmpty()) { QString rightOperand = operands.pop(); QString leftOperand = operands.pop(); QChar op = operators.pop(); QString expression = op + leftOperand + rightOperand; operands.push(expression); } return operands.pop(); } int precedence(QChar op) { switch(op.toLatin1()) { case '+': case '-': return 1; case '*': case '/': return 2; case '^': return 3; default: return 0; } } ``` 该代码使用两个实现中缀表达式前缀表达式。`operators`用于存储运算符,`operands`用于存储操数和子表达式。遍历中缀表达式时,如果当前字符是数字或字母,则将其解析为操数并压入`operands`;如果当前字符是右括号,则将其压入`operators`;如果当前字符是左括号,则将`operators`的运算符弹出,与`operands`弹出的两个操数构成一个子表达式,然后将该子表达式压入`operands`,直到`operators`弹出的运算符为左括号;如果当前字符是运算符,则将其与`operators`的运算符比较,如果当前运算符的优先级小于等于`operators`顶运算符的优先级,则将`operators`弹出的运算符与`operands`弹出的两个操数构成一个子表达式,然后将该子表达式压入`operands`,直到`operators`为空或弹出的运算符的优先级大于当前运算符的优先级。最后,将`operands`的元素合并成一个前缀表达式并返回。`precedence`函数用于获取运算符的优先级。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值