關於計算數學表達式的方法有很多種,一般人們習慣是用中綴表達式去寫,而計算機並不能很好理解與計算,計算起來也很麻煩,如何去寫呢?
Calculator.java-CSDN下載 https://download.csdn.net/download/weixin_44688297/11897934
在這裏我只會寫我的算法以及思想,代碼已經發出來。還有如何轉化成後綴表達式,這裏不會細說,有時間我再補。
先說一下爲什麼要用動態數組呢?爲什麼不用棧?因爲我有一個對負號特殊的處理,動態數組的好處是我可以隨便指定一個位置進行插入,方法很簡單。
算法思想:利用動態數組實現棧。
1.先將表達式中的特殊的負號(將每一個左括號(前面的負號)轉化成減號,再其前面加上一個0,因爲這樣就可以區分負號和減號。例如:18/48-(-(4+5))將這種類型轉化成18/48-(0-(4+5))然後將其計算,因爲我的算法裏面不能對-(這種情況的負號進行區分,所以就想到了這種方法,爲什麼不寫算法去區分呢?因爲這種情況你根本無法預知會出現多少次,所以循環的判斷語句無法寫,我還不如直接對這種特殊的情況處理。
代碼:
//這裏的代碼需要自己處理,後面我會將完整的代碼全部發出,計算的也會發
ArrayList<Character>epress = new ArrayList<Character>();//對負號處理是動態數組
//18/48-(-(4+5))將這種類型轉化成18/48-(0-(4+5))然後將其計算
for (int i = 0; i < expression.length(); i++) {
char a = expression.charAt(i);
epress.add(a);
}
boolean v = true;
int k = 0;
while (v){
if (epress.get(k) == '-' && k == 0){
if (epress.get(k + 1) == '(') {
epress.add(0, '0');
k += 3;//向後移動三位0(-,移動到下一個運算符
}else {
v = false;
}
}else if (epress.get(k) == '-' && epress.get(k-1) == '('){
epress.add(k,'0');
k += 3;//向後移動三位0(-,移動到下一個運算符
}else {
k++;
}
if (k == epress.size()){
v = false;
}
}
expression = "";//令表達式爲空,然後依次將對負號處理完的動態epress裏面的內容重新賦給表達式
for (int i = 0; i < epress.size(); i++) {
expression += epress.get(i);
}
中綴轉化後綴表達式
ArrayList operand = new ArrayList();//操作數動態數組
ArrayList<Character> operator = new ArrayList<Character>();//運算符動態數組
ArrayList<Character>epress = new ArrayList<Character>();//對負號處理是動態數組
//以下是計算表達式轉化成後綴表達式
String expre = "";//存實數
for (int i = 0; i < expression.length(); i++) {
char a = expression.charAt(i);
if (a == '-') {
if (i > 0) {
if (expression.charAt(i-1) == '(') {//括號後面是負數的處理
expre += a;
}
else {
if (!"".equals(expre)) {//如果不爲空
double num = Double.valueOf(expre);
operand.add(num);
expre = "";
}
int length = operator.size();
if (length >= 1 ) {//-符號壓棧與出棧
if (operator.get(length - 1) == '+' || operator.get(length - 1) == '-') {
operand.add(operator.get(length - 1));
operator.remove(length - 1);
}else if (operator.get(length - 1) == '*' || operator.get(length - 1) == '/'){
int size = operator.size();
while (size > 0) {//取棧
if (operator.get(size - 1) != '(') {
operand.add(operator.get(size - 1));
}
operator.remove(size - 1);
size--;
}
operator.add(a);
continue;
}
}
operator.add(a);
}
}else {
expre += a;
}
} else if ((a <= '9' && a >= '0') || a == '.') {
expre += expression.charAt(i);
if (i == expression.length() - 1) {//最後一個爲數字
double num = Double.valueOf(expre);
operand.add(num);
expre = "";
}
} else {
if (!expre.equals("")) {
double num = Double.valueOf(expre);
operand.add(num);
expre = "";
}
int size = operator.size();
if (size == 0 || a == '(') {//運算符棧爲空
operator.add(a);
} else if (a != ')') {
if (operator.get(size - 1) == '(') {
operator.add(a);//壓棧
} else if (operator.get(size - 1) == '*' || operator.get(size - 1) == '/') {
if (a == '+' ) {//取棧並壓棧
while (size > operator.lastIndexOf('(') + 1) {
if (operator.get(size - 1) != '(') {
operand.add(operator.get(size - 1));
}
operator.remove(size - 1);
size--;
}
operator.add(a);
} else {
operand.add(operator.get(size - 1));
operator.remove(size - 1);
operator.add(a);
}
} else if (operator.get(size - 1) == '+' || operator.get(size - 1) == '-') {
if (a == '+' ) {//取棧並壓棧
while (size > operator.lastIndexOf('(') + 1) {
if (operator.get(size - 1) != '(') {
operand.add(operator.get(size - 1));
}
operator.remove(size - 1);
size--;
}
operator.add(a);
} else {//壓棧
operator.add(a);
}
}
} else {//取棧
while (size > operator.lastIndexOf('(') + 1) {
if (size - 1 >= 0) {
operand.add(operator.get(size - 1));
operator.remove(size - 1);
}
size--;
}
if (size > 0) {
operator.remove(size - 1);
} else if (size == 0) {
operator.remove(0);
}
}
}
}
//如果operator裏面還有運算符,就將其弄到後綴表達式的最後
int size = operator.size();
while (size > 0){
operand.add(operator.get(size-1));
operator.remove(size-1);
size--;
}
System.out.println(operand);//輸出已經轉好的後綴表達式
}
2.將處理後的表達式轉化成後綴表達式(逆波蘭表達式)
用棧的思想以及動態數組,
3.計算後綴表達式(逆波蘭表達式)
//找到最早出現的一個運算符,然後取其前面兩個數字進行運算
//後綴表達式計算算法演示
*[-2.5, 3.2, -5.0, 4.0, +, , 3.0, /, -2.0, /, 9.0, , +]
[-2.5, 3.2, -5+4, * , 3.0, /, -2.0, /, 9.0, , +]
[-2.5, 3.2(-5+4) , 3.0 /, -2.0, /, 9.0, , +]
[-2.5, 3.2(-5+4), -2.0 /, 9.0, , +]
[-2.5, 3.2(-5+4)/3.0/-2.0 , 9.0, , +]
[-2.5, 3.2(-5+4)/3.0/-2.09.0, +]
如果大家需要更加多功能計算表達式的話,我後面還寫了一個有三角函數,有ln,log,次方的,需要的話私聊我。。