牛客网在线编程题目
题目要求:
描述
请写一个整数计算器,支持加减乘三种运算和括号。
输入:"1+2"
输出:3

解:

  1. 分析题目
    其实现步骤主要包括三大函数进行实现,这里采用的是midtransportBehind(中缀转为list)transport(中缀表达式转换为后缀表达式),caluace(计算表达式)。三个部分

  2. 中缀转为list
    先说一下这个函数的编写吧,其实现的原理依据就是通过ASCII码进行判断,对数字符号和非数字符号依次遍历进行放置在list结构中,先给出代码:

     //中缀转list
     private List<String> midtransportBehind(String s) {
         //定义一个list
         List<String> ls = new ArrayList<String>();
         int i = 0;//作为一个指针遍历
         String str;//多位数拼接
         char c;//作为存储的 
         do {//不是数字符号,数字符号的范围在48-57之间表示0-9
             if( (c=s.charAt(i))< 48 || (c=s.charAt(i)) > 57  ){
                 ls.add(""+c);
                 i++;//后移
             }else{
                 str = "";//进行数字字符的拼接
                 while(i < s.length() &&  (c = s.charAt(i))>= 48 && (c = s.charAt(i))<= 57   ){
                     str = str+c;
                     i++;
                 }
                 ls.add(str);
             }
    
         } while (i<s.length());
         return ls;
     }
  3. 中缀转后缀

     该部分所实现的代码主要根据采用一个栈和一个arraylist的数列表进行实现,
     1、首先是定义栈和数列
    //定义一个符号栈
         Stack<String> stack1 = new Stack<String>();
         //不需要定义一个数字栈,直接使用一个ArrayList
         List<String> stack2 = new ArrayList<String>();

    其次是在遍历上面转化的list链表中的式子进行分情况判断:
    1、若为数字-〉进入list
    2、若匹配到左括号-〉进栈
    3、匹配到右括号-〉进行检查栈顶的元素是否为左括号,如果不是泽则进行出栈。
    4、若遇到优先级的问题需要对优先级进行栈顶与入站字符进行判断,,栈顶的元素如果高于要加入的元素,这就需要对其进行出栈进行加入队列,最后的字符进行入栈。
    代码如下:

    //中缀转后缀
     private List<String> transport(List<String> ls) {
         //定义一个符号栈
         Stack<String> stack1 = new Stack<String>();
         //不需要定义一个数字栈,直接使用一个ArrayList
         List<String> stack2 = new ArrayList<String>();
         //遍历栈
         for(String eleString: ls){
             if(eleString.matches("\\d+")){
                 stack2.add(eleString);
             }else if(eleString.equals("(")){
                 stack1.push(eleString);//进栈
             }else if(eleString.equals(")")){
                 while(!stack1.peek().equals("(")){
                     stack2.add(stack1.pop());
                 }
                 stack1.pop();//消除做括号
             }else{
                 //当优先级小雨等于栈顶的优先级
                 while(stack1.size() != 0 && Operation.getOperation(stack1.peek()) >= Operation.getOperation(eleString)){
                     stack2.add(stack1.pop());
                 }
                 stack1.push(eleString);
             }
         }
    
         while(stack1.size() != 0){
             stack2.add(stack1.pop());
         }
    
         return stack2;
     }
  4. 后缀表达式计算
    计算表达式依据的也是对栈的操作,通过出栈和入栈进行配合进行计算取值,若检测到数字出现时,将其压入栈中,检测到字符时进行判断,并将其数据出栈进行计算,计算结果入栈,最后返回栈内结果便是最终的计算结果。

    private int caluace(List<String> list) {
         int res = 0;
         // TODO Auto-generated method stub
         Stack<String> stack = new Stack<String>();
         //开始遍历
         for(String eleString : list){
             if(eleString.matches("\\d+")){
                 stack.push(eleString);//压入栈中
             }else {
                 int num1 = Integer.parseInt(stack.pop());
                 int num2 = Integer.parseInt(stack.pop());
                 if(eleString.equals("+")){
                     res = num1+ num2;
                 }else if(eleString.equals("-")){
                     res = num2 - num1;
                 }else if(eleString.equals("*")){
                     res = num1 * num2;
                 }else if(eleString.equals("/")){
                     res = num2/num1;
                 }else {
                     throw new RuntimeErrorException(null,"运算符错误");
                 }
                 //结束后进行结果压栈
                 stack.push(""+res);
             }
    
         }
    
    
    return Integer.parseInt(stack.pop());
}
这里进行优先级判断的类主要如下:

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 getOperation(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;
}

}
```