利用ArrayStack实现前缀表达式的计算(JAVA语言)

实现原理

  • 创建两个栈,分别为操作符栈和操作数栈,操作符栈存放“+”,“-”,“*”,“/”运算符,操作数栈存放需要进行操作的数。

  • 通过输入一个前缀表达式,通过inserblanks将表达式格式化。再调用split函数分割表达式。

  • 将分割后的表达式,用for循环遍历,当遇到长度为0的字符串时,直接跳过本次循环。其他符号操作如下:

  • 当 “+” 和 “-” 入栈时判断栈内是否有其他运算符,如果有的话,则将栈内运算符处理过后再入栈。

  • 当 “*” 和 “/” 入栈时,判断操作符栈内是否存在 “ * ” 和 " / " ,如果有的话,则先处理栈内的操作符后再入栈。

  • 当输入括号时,如果此时栈内为空,则直接入栈,如果此时栈内有匹配括号,则将匹配域内的符号一起处理,然后将括号弹栈。

  • 具体原理图如下:

其中:格式化处理表达式的代码为:

//输入一个表达式字符串,遍历字符串,在(,),+,,-,*,/前后加上一个空格,便于调用字符串切割函数
private static StringBuffer insertBlanks(String str) {
        StringBuffer str2 = new StringBuffer();
        for (int i = 0; i < str.length(); i++) {
            char c = str.charAt(i);
            if (c == '(' || c == ')' || c == '+' || c == '-' || c == '*' || c == '/') {
                if (!str2.toString().endsWith(" ")) {
                    str2.append(" ");
                }
                str2.append(str.charAt(i));
                str2.append(" ");
            } else {
                str2.append(str.charAt(i));
            }
        }
        return str2;
    }

处理了前缀表达式后,调用String类的split函数切割函数切割字符串,然后再将字符串入栈进行操作,具体代码如下:

import java.util.Scanner;

public class ArrayStackTest4 {
    public static void main(String[] args) {
        ArrayStack<String> arrayStack = new ArrayStack<>();
        Scanner scanner = new Scanner(System.in);
        String str = scanner.nextLine();
        StringBuffer str3 = insertBlanks(str);//格式化字符串
        String[] arrStr = str3.toString().split(" ");
        ArrayStack<String> stringArrayStack = new ArrayStack<>();
        ArrayStack<Float> integerArrayStack = new ArrayStack<>();


        for(String st:arrStr){
            //处理空格情况,直接跳过
            if(st.length()==0){
                continue;
            }
            if(stringArrayStack.isEmpty()&&(st.equals("+")||
                    st.equals("-")||
                    st.equals("*")||
                    st.equals("/"))){
                   stringArrayStack.push(st);
                   continue;
            }
            //当操作栈入栈+或者-的时候,之前的操作全部出栈。
            if(st.equals("+")||st.equals("-")){

                while(!stringArrayStack.isEmpty()&&(
                        stringArrayStack.peek().equals("+")||
                        stringArrayStack.peek().equals("-")||
                        stringArrayStack.peek().equals("*")||
                        stringArrayStack.peek().equals("/"))){
                        processAnOperater(integerArrayStack,stringArrayStack);
                }
                stringArrayStack.push(st);
                //当操作栈入栈*或者/的时候,操作栈中的*或者/出栈
            }else if(st.equals("*")||st.equals("/")){
                while(!stringArrayStack.isEmpty()&&(stringArrayStack.peek().equals("*")||
                        stringArrayStack.peek().equals("/"))){
                    processAnOperater(integerArrayStack,stringArrayStack);
                }
                stringArrayStack.push(st);
                //当加入左括号造的时候,直接入栈
            }else if(st.equals("(")){
                stringArrayStack.push("(");
                //当加入右括号的时候,清空栈内的一切操作,并将左括号弹栈。
            }else if(st.equals(")")){
                while(!stringArrayStack.peek().equals("(")){
                    processAnOperater(integerArrayStack,stringArrayStack);
                }
                stringArrayStack.pop();
            }else {
                integerArrayStack.push(Float.parseFloat(st));//将字符串中的数字转化为Int类型放入数字栈
            }

        }
        if(!stringArrayStack.isEmpty()){
            processAnOperater(integerArrayStack,stringArrayStack);
        }
        System.out.println(integerArrayStack.pop());

    }

    private static void processAnOperater(ArrayStack<Float> integerArrayStack, ArrayStack<String> stringArrayStack) {
        float num1=integerArrayStack.pop();
        float num2=integerArrayStack.pop();
        if(stringArrayStack.peek().equals("+")){
            integerArrayStack.push(num2+num1);
        }
        if(stringArrayStack.peek().equals("-")){
            integerArrayStack.push(num2-num1);
        }
        if(stringArrayStack.peek().equals("*")){
            integerArrayStack.push(num1*num2);
        }
        if(stringArrayStack.peek().equals("/")){
            integerArrayStack.push(num2/num1);
        }
        stringArrayStack.pop();
    }

    private static StringBuffer insertBlanks(String str) {
        StringBuffer str2 = new StringBuffer();
        for (int i = 0; i < str.length(); i++) {
            char c = str.charAt(i);
            if (c == '(' || c == ')' || c == '+' || c == '-' || c == '*' || c == '/') {
                if (!str2.toString().endsWith(" ")) {
                    str2.append(" ");
                }
                str2.append(str.charAt(i));
                str2.append(" ");
            } else {
                str2.append(str.charAt(i));
            }
        }
        return str2;
    }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值