1. 程式人生 > >Java實現簡單四則運算

Java實現簡單四則運算

工作之餘,突然想用java實現一下四則運算,經過簡單的構思,很快就有了思路,就完成了一個簡單版本。


經過慎重考慮,覺得使用棧還是要比陣列或者List容易對符號和數字進行控制。

我使用兩個棧,分別儲存數字和符號,然後判斷當前符號和前一個符號的運算級別,來決定是否進行一次彈棧運算(就是挨著前一個運算子號的兩個數,是不是有必要進行一次運算)。

經過簡單的測試,標準的四則運算,在下面程式碼是沒有問題的。

如果再加括號,那就是在這個基礎上,新增去括號的流程就可以,等那天有時間了,再完善吧。


所有原始碼如下:

package com.rq.spring.main;



import java.util.Stack;
/**
 * 使用棧完成的簡單四則運算,不帶有任何括號
 * 測試時,請輸入標準的四則運算式
 * 待優化的地方很多,各位大神,多提意見
 * @author 任強
 *
 */
public class TestStackSimpleOperation {


public static void main(String[] args) {
//簡單語法
// Stack<String> stack = new Stack<>();//建立一個棧,字串型別
//
// stack.push("a");//壓棧
// stack.push("b");
// stack.push("c");
//
// while(!stack.empty()){//判斷是否為空
// String s = stack.pop();//彈棧
// System.out.println(s);
// }
//另一種遍歷棧的方法
//
Iterator<String> it = stack.iterator();
// while(it.hasNext()){
// String s = it.next();
// System.out.println(s);
// }
//測試自己編寫的方法
// System.out.println(simpleOperation("1+2+3*5+4*6-7/7+1"));//42
// System.out.println(simpleOperation("1*2*3*4*5*6+1+2*5+9*6+9"));//794
// System.out.println(simpleOperation("5+6/3*8-9+45*67+95/5+8-85"));//2969
System.out.println(simpleOperation("1+2+3-4+5*6-7+8-9*6/2/1+99/33*55-951"));//-780
}
/**
* 簡單四則運算
* @param equation 四則運算式
* @return 運算結果
*/
public static int simpleOperation(String equation){
Stack<Integer> nums = new Stack<>();//儲存運算數字的棧
Stack<String> symbols = new Stack<>();//儲存運算子號的棧
while(equation != null && equation.length() > 0){
int symIndex = getLastIndex(equation);
if(symIndex == -1){//表示已經到了運算式的結尾,需要返回結果了
int num = Integer.valueOf(equation);
return getResult(num, symbols.pop(), nums.pop());
}
int num = Integer.valueOf(equation.substring(0, symIndex));
nums.push(num);
String sym = equation.substring(symIndex, symIndex + 1);
//完成計算流程
String lastSym = symbols.empty() ? null : symbols.peek();//獲取前一個運算子
//前一個運算子存在,且它的等級是不小於當前運算子,就進行一次運算,
//把數字棧中的後兩個元素彈棧操作,使用前一個運算子完成計算
//使用while的原因是可能在符號棧中需要繼續進行往前一步的運算
while(lastSym != null && getLevel(lastSym) >= getLevel(sym)){
nums.push(getResult(nums.pop(), symbols.pop(), nums.pop()));
lastSym = symbols.empty() ? null : symbols.peek();
}
symbols.push(sym);
equation = equation.substring(symIndex + 1);
}
return 0;
}
//計算結果,因為是彈棧操作,所有後彈出的數字在運算子前面
private static int getResult(int a, String sym, int b){
switch(sym){
case "+" : return b + a;
case "-" : return b - a;
case "*" : return b * a;
default : return b / a;
}
}
//運算子等級,等級越高需要越先完成計算
private static int getLevel(String sym){
return sym.equals("+") || sym.equals("-") ? 1 : 2 ;
}
//最接近運算式起始的符號位置,用來確定馬上要參與運算的數字和該數字之後的運算子
private static int getLastIndex(String equation){
int addIndex = equation.indexOf("+");
int symIndex = -1;
if(addIndex > -1){
symIndex = addIndex;
}
int subIndex = equation.indexOf("-");
if(subIndex > -1 && (symIndex == -1 || symIndex > subIndex)){
symIndex = subIndex;
}
int mulIndex = equation.indexOf("*");
if(mulIndex > -1 && (symIndex == -1 || symIndex > mulIndex)){
symIndex = mulIndex;
}
int divIndex = equation.indexOf("/");
if(divIndex > -1 && (symIndex == -1 || symIndex > divIndex)){
symIndex = divIndex;
}
return symIndex;
}
}