逆波兰计算器的实现

1,基本思路

		1,将中缀表达式存入一个集合,方便遍历使用
		2,将中缀表达式,转换为后缀表达式(逆波兰表达式)
		3,使用后缀表达式计算求值

2,具体实现思路

		1,中缀表达式存入集合:
			首先,对字符串从左至右进行遍历,如果遇到符号,则直接存入集合,如果遇到数
			字,则判断是否是多位数,如果是多位数,将多位数存入集合,如果不是多位数,
			直接尺存入集合。

		2,中缀表达式转后缀表达式:

在这里插入图片描述

			注意:因为操作数栈数s2没有出栈操作,所以可以使用集合代替,效率更高

		3,使用后缀表达式计算求值:
			首先,从左至右扫描后缀表达式,遇到数字时,将其压入堆栈,遇到运算符时,弹出栈
			顶的两个数,用运算符对他们做相应的计算,并将结果入栈。重复上述过程直至表达式
			最右端。最后栈中的值即为表达式的结果。

3,代码实现

1,计算工具类
package 数据结构..逆波兰计算器;
//计算工具类
public class JSUtils {
    //1,判断运算符的优先级,数字越大,则优先级就越高.
    public static int priority(String oper){
        if(oper.equals("+")||oper.equals("-")){
            return 0;
        }
        else if(oper.equals("*")||oper.equals("/")){
            return 1;
        }
        return -1;
    }

    //2,计算方法
    public static int cal(int num1,int num2,String oper){
        switch (oper){
            case "+":
                return num1+num2;
            case "-":
                return num2-num1;
            case "*":
                return num1*num2;
            case "/":
                return num2/num1;
            default:
                return 0;

        }
    }
}

2,逆波兰表达式的入栈,转换,计算
package 数据结构..逆波兰计算器;

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

//逆波兰计算器的实现
public class NiBoLan {

    //1,将中缀表达式存入一个集合
    public  static List<String> zToL(String expression){
        //创建一个集合,存放中缀表达式
        List<String> z=new ArrayList<String>();
        //对字符串进行遍历,将其存入集合
        char c;
        int index;
        String str;
        for(index=0;index<expression.length();){
            //如果当前字符是非数字,则直接存入集合
            if((c=expression.charAt(index))<48||((c=expression.charAt(index))>57)){
                z.add(""+c);
                index++;
            }
            //如果当前字符是数字,则判断是否是多位数
            else{
                //将数字拼接到str中
                str="";
                while (index<expression.length()&&(c=expression.charAt(index))>=48&&(c=expression.charAt(index))<=57){
                    str+=c;
                    index++;
                }
                z.add(str);
            }
        }
        return z;
    }
    //2,将中缀表达式转换为后缀表达式
    public static List<String> zTOH(List<String> z){
        //创建一个集合存放后缀表达式
        List<String> h=new ArrayList<String>();
        //创建一个符号栈
        Stack<String> s=new Stack<String >();
        //从左向右扫描z集合中的中缀表达式
        for (String zh:z) {
            //如果是数字,则直接放到h集合
            if(zh.matches("\\d+")){
                h.add(zh);
            }
            //如果是符号
            //1,如果是左括号(,则直接入符号栈
            else if(zh.equals("(")){
                s.push(zh);
            }
            //2,如果是有括号")",则将符号栈中的栈顶符号弹出,存入h集合,直到遇见左括号"("
            else if(zh.equals(")")){
                while (!s.peek().equals("(")){
                    h.add(s.pop());
                }
                s.pop();
            }
            //3,如果不是括号,则判断栈是否为空,或者栈顶是否是左括号,若成立,直接入栈,
            //若不成立,比较当前符号和栈顶符号的优先级,如果优先级高,则直接入栈,否则,取出栈顶元素,继续比较
            else {
                //不成立
                while ((!s.isEmpty())&&(!s.peek().equals("("))&&(JSUtils.priority(s.peek())>=JSUtils.priority(zh))){
                    h.add(s.pop());
                }
                //成立,将符号入栈
                s.push(zh);
            }
        }
        //将栈里剩余符号取出
        while (!s.isEmpty()){
            h.add(s.pop());
        }
        return h;
    }

    //计算得出结果
    public static int sum(List<String> h){
        //创建一个栈存放运算结果
        Stack<String> s=new Stack<String>();
        //遍历集合
        for (String ch:h) {
            //如果遇到数字,则将其压入栈
            if(ch.matches("\\d+")){
                s.push(ch);
            }
            //如果遇到符号,则取出栈中前两个数字,运算,将结果存入栈
            else{
                int res = JSUtils.cal(Integer.parseInt(s.pop()), Integer.parseInt(s.pop()), ch);
                s.push(Integer.toString(res));
            }
        }
        return Integer.parseInt(s.pop());
    }
}

3,测试类
package 数据结构..逆波兰计算器;

import java.util.Scanner;

public class Test {
    public static void main(String[] args) {
        Scanner in=new Scanner(System.in);
       while (true){
           System.out.println("请输入计算式:");
           String s=in.next();
           int sum = NiBoLan.sum(NiBoLan.zTOH(NiBoLan.zToL(s)));
           System.out.println(sum);
       }
    }
}


版权声明:本文为weixin_51721994原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/weixin_51721994/article/details/122390637