四则运算

源码:

Arithmetic:

  1 package arithmetic;
  2 
  3 import java.util.ArrayList;
  4 import java.util.HashMap;
  5 import java.util.Map;
  6 import java.util.Stack;
  7 
  8 /**
  9  * 四则运算
 10  *
 11  * @author lilongrong
 12  * @version 2020/3/28
 13  * @
 14  */
 15 
 16 public class Arithmetic {
 17     private String arithmetic;
 18 
 19     //public ArrayList<Character> rpnArr = new ArrayList<>(); //用于存储逆波兰式
 20     private int flag = 0;   //用于记录存储的顺序
 21     private Map<Integer, Integer> intMap = new HashMap<>();  //用于存储数字
 22     private Map<Integer, Character> charMap = new HashMap<>();  //用于存储运算符
 23     private Map<Character, Integer> map = new HashMap<>();    /*用于存四则运算符号的优先级*/
 24     private ArrayList<Integer> sum = new ArrayList<>();   /*可能不是一位数字,那么就需要对每个数字线存储起来,遇到符号时就将存储起来的数字进行运算*/
 25     private Stack<Character> stack = new Stack<>();   /*存储四则运算的符号*/
 26     private int add = 0;
 27 
 28     /**
 29      *input a kind String expression,and then output a kind of int result.
 30      *
 31      *
 32      * @param arithmetic expression like "6+(8-7)+5*6+9-12/2"
 33      */
 34     public Arithmetic(String arithmetic)
 35     {
 36         this.arithmetic = arithmetic;
 37     }
 38 
 39 
 40     /*对每个字符进行相应的处理*/
 41     private void analyze(String arithmetic) throws ArithmeticHandleException
 42     {
 43         /*定义四则运算符号的优先级*/
 44         map.put('+', 1);
 45         map.put('-', 1);
 46         map.put('*', 2);
 47         map.put('/', 2);
 48         map.put('(', 3);
 49         map.put(')', 3);
 50 
 51         for (int i = 0; i < arithmetic.length(); i++)
 52         {
 53             char nowChar = arithmetic.charAt(i);    /*取出第一个字符*/
 54             if (nowChar == '+' || nowChar == '-' || nowChar == '*' || nowChar == '/' || nowChar == '(' || nowChar == ')')
 55             { /*如果是运算符,就要准备入栈了*/
 56                 if (sum.size() != 0)
 57                 {    /*入栈之前要先将存储在sum里的数据输出出来*/
 58                     summation();
 59                 }
 60 
 61                 if (nowChar != ')' && (stack.empty() || map.get(nowChar) > map.get(stack.peek()) || stack.peek() == '('))
 62                 {    /*入栈*/
 63                     stack.push(nowChar);
 64                 } else {
 65                     while (!stack.isEmpty() && nowChar >= map.get(stack.peek()))
 66                     {  /*当栈不为空并且当前运算符的优先级不小于栈顶运算符时*/
 67                         if (stack.peek() == '(' || stack.peek() == ')')
 68                         {   /*对于括号运行符不需要进行输出*/
 69                             stack.pop();
 70                             break;
 71                         }
 72 
 73                         charMap.put(flag++, stack.pop());
 74                     }
 75 
 76                     if (nowChar != ')')
 77                     {       /*将当前运算符入栈,如果是右括号的话就不用入栈了,因为当遇到右括号是,栈里面必然有左括号,所以右括号要随着左括号一起丢掉*/
 78                         stack.push(nowChar);
 79                     }
 80                 }
 81                 continue;
 82             }
 83             else
 84                 {    /*当不是运算符时,就进行数字的处理*/
 85                     int num = Integer.valueOf(nowChar) - 48;    /*Integer.valueOf(nowChar)输出的是字符的ASCII码值,要将它转化为实际数字*/
 86                     if(num<0||num>9)
 87                     {
 88                         String message = "There are illegal characters in it";
 89                         throw new ArithmeticHandleException(message);
 90                     }
 91                     else
 92                     {
 93                         sum.add(num);   /*可能不是一位数,所以可以先将该数字存储起来*/
 94                     }
 95                 }
 96         }
 97 
 98         if (sum.size() != 0)
 99         {  /*此时sum里面可能还会有存储起来的数字,但还没输出,此时要进行输出了*/
100             for (int j = 0; j < sum.size(); j++)
101             {
102                 summation();
103             }
104         }
105 
106         while (!stack.isEmpty())
107         {  /*和上面的原因一样*/
108             charMap.put(flag++, stack.pop());
109         }
110     }
111 
112     /*将数组中的数字求和*/
113     private void summation()
114     {
115         int pow = 0;
116         for (int j = sum.size() - 1; j >= 0; j--)
117         {
118             add = (int) (add + sum.get(j) * Math.pow(10, pow++));   /*求幂运算*/
119         }
120         sum.clear();    /*清除ArrayList集合*/
121         intMap.put(flag++, add);
122         add = 0;    /*归零,不然下次会接着累加*/
123     }
124 
125     public int operation() throws ArithmeticHandleException
126     {
127         Stack<Integer> stack = new Stack<>();   /*用于存放数据*/
128 
129         Arithmetic arithmetic = this;
130         arithmetic.analyze(this.arithmetic);
131         for (int i = 0; i < arithmetic.intMap.size() + arithmetic.charMap.size(); i++)
132         {    /*遍历两个集合*/
133             if (arithmetic.intMap.get(i) == null)
134             {
135                 switch (arithmetic.charMap.get(i))
136                 {
137                     case '-':   /*因为是减号,所以要考虑顺序*/
138                         int one = stack.pop();
139                         int two = stack.pop();
140                         stack.push(two - one);
141                         break;
142                     case '+':
143                         stack.push(stack.pop() + stack.pop());
144                         break;
145                     case '*':
146                         stack.push(stack.pop() * stack.pop());
147                         break;
148                     case '/':   /*同减号,是因为顺序*/
149                         int first = stack.pop();
150                         int second = stack.pop();
151                         stack.push(second / first);
152                         break;
153                 }
154             }
155             else
156                 {
157                 stack.push(arithmetic.intMap.get(i));
158                 }
159         }
160         return stack.pop();
161     }
162 
163 }

异常处理:ArithmeticHandleException:

1 package arithmetic;
2 
3 public class ArithmeticHandleException extends Exception {
4     ArithmeticHandleException (String message)
5     {
6         super(message);
7     }
8 }

主函数运行:

 1 import arithmetic.Arithmetic;
 2 import arithmetic.ArithmeticHandleException;
 3 
 4 import java.util.Scanner;
 5 
 6 public class MainClass {
 7     public static void main(String[] args)
 8     {
 9         Scanner scanner = new Scanner(System.in);
10         String string = scanner.next();
11         Arithmetic arithmetic = new Arithmetic(string);
12         try
13         {
14             System.out.print(arithmetic.operation());
15         }
16         catch (ArithmeticHandleException AE)
17         {
18             AE.printStackTrace();
19         }
20     }
21 
22 }

目前处在调试阶段,还有很多东西需要改进。

posted @ 2020-03-28 10:34  骄傲使人进步  阅读(135)  评论(0编辑  收藏  举报