用Java实现输入算数式计算值 ---中缀表达式转换为后缀表达式

基本要求

实现文本计算器,支持加减乘除、括号。

基本思路:
首先是先将输入的文本字符串 通过正则表达式转换为一个个字符 再将其转换为后缀表达式:
其中中缀表达式转换为后缀表达式 需要使用到栈的相关操作 还有一些基本的规则:
1.遇到操作数,直接输出;
2.栈为空时,遇到运算符,入栈;
3.遇到左括号,将其入栈;
4.遇到右括号,执行出栈操作,并将出栈的元素输出,直到弹出栈的是左括号,左括号不输出;
5.遇到其他运算符’+”-”*”/’时,弹出所有优先级大于或等于该运算符的栈顶元素,然后将该运算符入栈;
6.最终将栈中的元素依次出栈,输出。
经过上面的步骤,得到的输出既是转换得到的后缀表达式。

还有就是当输入的字符中数字的位数不是一位时 分成字符时就需要特别考虑

还有差错检测:对于输入的文本计算式需要先进行差错检测 如果时错误的表达式即不需要进行计算即可:

因为能力有限 写的代码数字三位时 就会计算错误
下面附上个人的代码 :



import java.util.Scanner;

/*文本计算器,支持加减乘除、括号。*/
//1+2*(4-3)/2 (10+20)*3/5-6 10+2*(40-3)/2
public class Calculate {
    public static String[] stack= new String[100];//定义栈
    public static int top=0;
    public static void push(String a) {//入栈操作
        if(top>=100) return;
        stack[top++]=a;
    }

    public static String pop() {//出栈操作
        if(top==0) return null;
        return stack[--top]; 
    }

    public static boolean isEmpty() {//判断栈是否为空
        if(top==0) return true;
        return false;
    }

    public static String getTop() {//获取栈顶元素
        if(top<100)
        return stack[top-1];
        return null;
    }

    public static void zl1(String[] s1,String[] s2) {//s2是后缀表达式
        int j=0;
        for(int i=0;i//遍历字符串
        {
             if(s1[i].equals("")) break;
             else if(isEmpty()&&(s1[i].equals("+")||s1[i].equals("-")||s1[i].equals("*")||s1[i].equals("/"))) {
                push(s1[i]);
            }
            else if(!s1[i].equals("+")&&!s1[i].equals("-")&&!s1[i].equals("*")&&!s1[i].equals("/")&&!s1[i].equals("(")&&!s1[i].equals(")")) {
                s2[j++]=s1[i];
            }
            else if(s1[i].equals("(")) push(s1[i]);
            else if(s1[i].equals(")")) {
                String q=pop();
                while(!isEmpty()&&!q.equals("(")) {
                    s2[j++]=q; q=pop();
                }
            }
            else if(s1[i].equals("+")||s1[i].equals("-")) {
                while(!isEmpty()&&(!getTop().equals("(")&&!getTop().equals(")")))
                s2[j++]=pop();
                push(s1[i]);
            }
            else if(s1[i].equals("*")||s1[i].equals("/")) {
                while(!isEmpty()&&(!getTop().equals("+")&&!getTop().equals("-")&&!getTop().equals("(")&&!getTop().equals(")")))
                s2[j++]=pop();
                push(s1[i]);
            }

        }
        while(!isEmpty()) s2[j++]=pop();

    }
    //计算方法
    public static double calculate(String[] s2) {
        double[] stack1= new double[100];//存放计算结果的栈
        int top1=0;
        for(int i=0;s2[i]!=null;i++) {
            if(!s2[i].equals("+")&&!s2[i].equals("-")&&!s2[i].equals("*")&&!s2[i].equals("/")) {
                stack1[top1++]= Double.parseDouble(s2[i]);
            }
            if(s2[i].equals("+")||s2[i].equals("-")||s2[i].equals("*")||s2[i].equals("/")) {
                if(s2[i].equals("+")) {
                    stack1[top1-2]=stack1[top1-2]+stack1[top1-1];
                    top1--;
                }
                if(s2[i].equals("-")) {
                    stack1[top1-2]=stack1[top1-2]-stack1[top1-1];
                    top1--;
                }
                if(s2[i].equals("*")) {
                    stack1[top1-2]=stack1[top1-2]*stack1[top1-1];
                    top1--;
                }
                if(s2[i].equals("/")) {
                    stack1[top1-2]=stack1[top1-2]/stack1[top1-1];
                    top1--;
                }
            }
        }
        return stack1[0];
    }
    public static void zl(String[] s) {//对输入的字符串进行处理

        for(int i=0;i<(s.length-1);i++) {
            if(!s[i].equals("+")&&!s[i].equals("-")&&!s[i].equals("*")&&!s[i].equals("/")&&!s[i].equals("(")&&!s[i].equals(")"))
            {
                if(!s[i+1].equals("+")&&!s[i+1].equals("-")&&!s[i+1].equals("*")&&!s[i+1].equals("/")&&!s[i+1].equals("(")&&!s[i+1].equals(")"))
                {
                    s[i]=s[i]+s[i+1];
                    for(int j=i+1;j<(s.length-1);j++) s[j]=s[j+1];
                    s[s.length-1]="";
                }
            }
        }

    }

    public static boolean panduan(String s) {//对表达式进行错误判断
        String w=s;
        int flag=0;
        for(int i=0;iif(w.charAt(i)=='('||w.charAt(i)==')') flag++;
        }
        if(flag%2!=0) {
            System.out.println("括号匹配错误!"); return false;
        }
        for(int i=0;iif(w.charAt(i)=='+'||w.charAt(i)=='-'||w.charAt(i)=='*'||w.charAt(i)=='/')
            {
                if(w.charAt(i+1)=='+'||w.charAt(i+1)=='-'||w.charAt(i+1)=='*'||w.charAt(i+1)=='/'||w.charAt(i+1)==')')
                {
                    System.out.println("运算符错误!"); return false;
                }
            }
            if(w.charAt(i)=='(') {
                if(w.charAt(i+1)=='+'||w.charAt(i+1)=='-'||w.charAt(i+1)=='*'||w.charAt(i+1)=='/'||w.charAt(i+1)=='/') {
                    System.out.println("运算符错误!"); return false;
                }
            }
        }
        String[] q=s.split("[0-9+-/*()]*");
        for(String a:q) {
            if(!a.equals("")) {
                System.out.println("算式中有特殊字符(不属于运算符或数字)!");
                return false;
            }
        }
        return true;
    }
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.println("输入正确的算数式:");
        String s= sc.nextLine();
        s=s.trim();
        if(panduan(s)) {
            String[] s1=s.split("");
            zl(s1);
            String[] s2= new String[s1.length];
            zl1(s1,s2);
            System.out.println("结果是:"+calculate(s2));
        }

    }
}

附上运行结果:
运行结果

下面还有附上一个同学写的代码:风格更加简洁(写的很好可以参考参考)

import java.util.Scanner;
import java.util.Stack;
class Expression{
    String exp;
    Expression(String s) { exp = s; }
    /*
     *  后缀表达式计算求值
     *  @params: 后缀表达式exp
     *  @return: 计算结果
     **/
    double exCompute() {
        Stack stack = new Stack();
        String bExp = this.midToBack(exp);
        String[] exps = bExp.split(" ");
        for(String s : exps) {
            if (s.length() == 0) continue;
            if (s.matches("[\\+\\-\\*/\\(\\)]")) {
                double y = stack.pop();
                double x = stack.pop();
                stack.push(compute(x, y, s));
            } else {
                stack.push(Double.parseDouble(s));
            } 
        }
        return stack.pop();
    }
    /*
     *  中缀表达式转后缀
     *  @params: 中缀表达式s
     *  @return: 后缀表达式backStr
     **/
    String midToBack(String s) {
        Stack stack = new Stack();
        String exp = addSpace(s);
        String[] exps = exp.split("[ \\t]");
        String backStr = "";
        for(String c : exps) {
            if (c.equals("(")) stack.push(c.charAt(0));       // 左括号 直接入栈
            else if (c.equals("+") || c.equals("-")) {        // 操作符 依次弹出优先级更高的至表达式队列中直至遇到更低优先级或者左括号
                while (stack.size() != 0){
                    if (stack.peek() == '(') break;
                    backStr += " " + stack.pop();
                }
                stack.push(c.charAt(0));
            }
            else if (c.equals("*") || c .equals("/")) {
                while (stack.size() != 0) {
                    if (stack.peek() == '(' || stack.peek() == '+' || stack.peek() == '-') break;
                    backStr += " " + stack.pop();
                }
                stack.push(c.charAt(0));
            }
            else if (c.equals(")")) {                         // 右括号 依次弹出所有操作符至表达式队列中直至遇到左括号
                while (stack.size() != 0) {
                    if (stack.peek() == '(') {
                        stack.pop();
                        break;
                    }
                    backStr += " " + stack.pop();
                }
            } else {                                         // 操作数 直接加到表达式中
                backStr += " " + c;
            }
        }
        while (stack.size() != 0) backStr += " " + stack.pop();
        return backStr;
    }
    /*
     *  将操作符扩展成带空格以支持浮点数转换
     *  @params: 中缀表达式s
     *  @return: 扩展中缀表达式s1
     **/
    String addSpace(String s) {
        String s1 = s.replace("+", " + ");
        s1 = s1.replace("-", " - ");
        s1 = s1.replace("*", " * ");
        s1 = s1.replace("/", " / ");
        s1 = s1.replace("(", " ( ");
        s1 = s1.replace(")", " ) ");
        return s1;
    }
    double compute(double x, double y, String s) {
        char c = s.charAt(0);
        switch(c) {
            case '+': return x+y;
            case '-': return x-y;
            case '*': return x*y;
            case '/': if(y != 0) return x/y;
            default: return 0;
        }
    }
}
class App{
    public static void main (String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.print("请输入四则运算表达式:");
        String s = sc.nextLine();
        Expression exp = new Expression(s);
        System.out.print("\n计算结果为:" + exp.exCompute());
    }
}
// 3+(2-5)*6/3 
// 5 * ( 4.1 + 2 -6 /(8-2))
// 5 * ( 4.1 + 2.9 )

你可能感兴趣的:(Java学习笔记)