zoukankan      html  css  js  c++  java
  • 求一个包加减乘除和小括号的字符串的结果

    解题思路和代码原型来源于牛课网, 我自己实现了一遍,添加了部分注释

      1 package problems_2016_08_10;
      2 
      3 import java.util.LinkedList;
      4 /*
      5 总述:
      6 一共有五个函数分别是:
      7                     
      8                     getvalue():
      9                           参数:待求的字符串、
     10                           作用:一个启动函数,调用value函数
     11                           返回值:返回value函数返回值的第一个参数,就是求出的值
     12 
     13                     value():
     14                           参数:总的待求的字符串,从哪一个位置开始求
     15                           作用:这个函数只是可以求不加小括号的情况。
     16                                   在这种情况下,把数字和加减乘除放进que双端链表中,并且在放的时候用addnum方法,将乘除处理掉,只剩加减和数字,再将que链表通过getnum方法求出具体的值,返回给上一层。
     17                                   因为不能处理小括号,所以碰见小括号就将括号里面的内容抛给下一层递归(value函数)。
     18                                   这个value函数只有当发现右括号就停止
     19                           返回值:value函数在返回求出的结果的时候,还要返回处理的右括号的位置的索引值
     20                     addnum()
     21                           参数:que双端链表(这个是在value函数里面定义的),一个待添加进来的数字(value里面的pre)
     22                           作用:将字符串中紧挨的数字(表示是一个多位数字)转化为一个数字,并且将他加入到que中,在加入时处理掉que中的乘除号
     23                           返回值:没有返回值。因为是在value内部调用的,将当层递归的que变成了只包含加减和数字的字符
     24 
     25                     getnum()
     26                           参数:只包含加减和数字的que
     27                           作用:将只包含加减和数字的que求出结果
     28                           返回值:返回的是每一层小括号中(也是每一层递归当中)的结果
     29                     main()
     30                           用来进行检测代码功能的函数
     31                     
     32 
     33 */
     34 public class ExpressionCompute {
     35 
     36     public static int getValue(String str) {
     37         return value(str.toCharArray(), 0)[0];
     38     }
     39 
     40     public static int[] value(char[] str, int i) {
     41         LinkedList<String> que = new LinkedList<String>();
     42         int pre = 0;
     43         int[] bra = null;
     44         while (i < str.length && str[i] != ')') {//如果i(当前操作位置)还没有到达最有端,并且还没有碰到右边的括号,那就继续执行这个递归函数
     45             if (str[i] >= '0' && str[i] <= '9') {//如果当前操作的是两个运算符号之间的数字
     46                 pre = pre * 10 + str[i++] - '0';//将字符串格式的数字转换为int,减'0'相当于减了这个字符的ascii码的值,字符串就变成数字了
     47             } else if (str[i] != '(') {//如果发现也没有碰到了左括号,那说明碰到的是运算符
     48                 addNum(que, pre);//这个函数的功能是在pre加入que时看一下que的最后一个字符(肯定是运算符)是否为乘除,是的话进行结算
     49                 que.addLast(String.valueOf(str[i++]));//在上面获取到结算的结果加入之后下一位肯定是运算符,也加入
     50                 pre = 0;//把pre(用来存放两个运算符之间的数值的变量)清零
     51             } else {//说明遇到左括号里 
     52                 bra = value(str, i + 1);//碰到了左括号,那么就调用这个函数本身,将左括号之后的内容加入到内层递归中(传入的是左括号的下一个位置的索引)
     53                 pre = bra[0];//value函数返回一个数组(第29行)   第一个参数为处理过的值
     54                 i = bra[1] + 1;//第二个是处理到的值,+1表示下次开始处理的位置
     55             }
     56         }
     57         addNum(que, pre);//最后没有遇到加减乘除  所以还要再来一次addnum
     58         return new int[] { getNum(que), i };//返回这一层递归中的值和 处理到的位置i
     59     }
     60 
     61     public static void addNum(LinkedList<String> que, int num) {//这个函数的作用可以看成和que.addLast类似,que.addLast是直接把符号插入到que中需要用到的方法,当时当你想插入数字时需要看一下前一个符号的情况,所以自己封装了一个稍微复杂点儿的类似的方法
     62         if (!que.isEmpty()) {//判断是否为空
     63             int cur = 0;
     64             String top = que.pollLast();//先弹出一个
     65             if (top.equals("+") || top.equals("-")) {
     66                 que.addLast(top);//如果之前是加减,直接把这个数字放进去就可以了
     67             } else {//如果之前的符号为乘除,那需要运算之后才能放入(保证que里面始终只放加减符号和数字)
     68                 cur = Integer.valueOf(que.pollLast());//再弹出一个
     69                 num = top.equals("*") ? (cur * num) : (cur / num);//将第二次弹出的(肯定是一个数字,由19  20行可知)
     70             }
     71         }
     72         que.addLast(String.valueOf(num));//为空的话直接插入num,不为空让算出的结果等于num,好巧妙,又省了几行代码
     73     }
     74 
     75     public static int getNum(LinkedList<String> que) {//getnum的方法的作用仅仅是求一个只包含加减和数字的数组,的运算结果
     76         int res = 0;//用来保存结果
     77         boolean add = true;//用来描述一种状态,其实就是区分加减
     78         String cur = null;//用来存放每次新的pollFirst()出来的值(是string类型的)
     79         int num = 0;//用来保存cur转换回来的num类型
     80         while (!que.isEmpty()) {//判断que里面是不是空的
     81             cur = que.pollFirst();//弹出双向列表第一个
     82             if (cur.equals("+")) {//如果弹出的是加号
     83                 add = true;//将add设置为true,用于下一个检测到数字的时候使用
     84             } else if (cur.equals("-")) {//如果弹出的是减号
     85                 add = false;//将add设置为false,用于下一个检测到数字的时候使用
     86             } else {//如果不为加减那么肯定就是数字了
     87                 num = Integer.valueOf(cur);//将字符类型的准换成数字类型
     88                 res += add ? num : (-num);//res+=(+num或者-num),三目运算符大大减少代码数量
     89             }
     90         }
     91         return res;//返回最后求出的结果
     92     }
     93 
     94     public static void main(String[] args) {//进行一些测试
     95         String exp = "48*((70-65)-43)+8*1";
     96         System.out.println(getValue(exp));
     97 
     98         exp = "4*(6+78)+53-9/2+45*8";
     99         System.out.println(getValue(exp));
    100 
    101         exp = "10-5*3";
    102         System.out.println(getValue(exp));
    103 
    104         exp = "-3*4";
    105         System.out.println(getValue(exp));
    106 
    107         exp = "3+1*4";
    108         System.out.println(getValue(exp));
    109 
    110     }
    111 
    112 }
  • 相关阅读:
    【bzoj1036】【ZJOI2008】树的统计
    AE基础(8)PageLayout属性设置和添加元素
    AE基础(7)布局控件与地图控件关联
    UtilityAction扩展
    UtilityAction
    AE基础(6)数据查询与选择
    NavigationAction
    LayerAction
    AE基础(5)鹰眼功能
    AE基础(4)画几何图形
  • 原文地址:https://www.cnblogs.com/tobemaster/p/5832995.html
Copyright © 2011-2022 走看看