package com.djb.calculatdemo;
import java.util.ArrayList;
import java.util.Stack;
import javax.management.RuntimeErrorException;
public class CalculatTest {
public static void main(String[] args) {
ArrayList<String> suffixfxpression = getSuffixfxpression("10.5+((2+3)*4)-5/2");
double calculate = calculate(suffixfxpression);
System.out.println(calculate);
}
/**
* 将中缀表达式字符串转成后缀表达式数组
* @param str 传入的中缀表达式字符串
* @return 后缀表达式数组
*/
private static ArrayList<String> getSuffixfxpression(String str){
//保存运算符号的栈
Stack<String> signStack = new Stack<String>();
//保存后缀表达式的数组
ArrayList<String> numList = new ArrayList<String>();
//保存当前遍历到的数字
StringBuffer curNum = new StringBuffer();
for (int i = 0; i < str.length(); i++) {
//当前遍历的字符
char ch = str.charAt(i);
if (ch >= 48 && ch <= 57 || ch == '.') {//遍历到是数字
curNum.append(ch);
//获取一个完整的数字
int j = i + 1;
while (true) {
if (j == str.length()) {
break;
}
if (str.charAt(j) >= 48 && str.charAt(j) <= 57 || str.charAt(j) == '.') {
curNum.append(str.charAt(j));
}else {
break;
}
j ++;
}
//将获取到的完整数字放入数组中
numList.add(curNum.toString());
//清空当前拼接的数字
curNum.delete(0, curNum.length());
i = j - 1;
}else if (ch == '(') {//遍历到左括号直接入符号栈
signStack.push(String.valueOf(ch));
}else if (ch == ')') {//遍历到右括号,将符号栈的符号依次加入到数组数组中,知道碰到左括号,再将左括号出栈
while (!signStack.peek().equals("(")) {
numList.add(signStack.pop());
}
signStack.pop();
}else {//遍历到运算符号时,如果当前运算符号优先级低于符号栈顶的优先级,将符号栈栈顶出栈加入到数字数字中,知道当前符号高于栈顶的优先级
while (signStack.size() > 0 && getSymbolGread(signStack.peek()) >= getSymbolGread(String.valueOf(ch))) {
numList.add(signStack.pop());
}
//最后将当前符号入栈
signStack.push(String.valueOf(ch));
}
}
//将符号栈的数据依次出栈加入到数字数组中
while (signStack.size() > 0) {
numList.add(signStack.pop());
}
return numList;
}
/**
* 根据后缀表达式计算结果
* @param array 后缀表达式的数组
*/
private static double calculate(ArrayList<String> array) {
Stack<String> numStack = new Stack<String>();
//正序遍历后缀表达式数组
for (String item : array) {
if (isSymbol(item)) {//遍历到运算符,顺序在栈中取出两个数,然后逆向让两个数运算,将运算的结果入栈
double result = 0;
double num1 = Double.parseDouble(numStack.pop());
double num2 = Double.parseDouble(numStack.pop());
if (item.equals("+")) {
result = num2 + num1;
}else if (item.equals("-")) {
result = num2 - num1;
}else if (item.equals("*")) {
result = num2 * num1;
}else if (item.equals("/")) {
result = num2 / num1;
}else {
throw new RuntimeErrorException(null, "非法的运算符");
}
numStack.push(String.valueOf(result));
}else {//遍历到数字,直接入栈
numStack.push(item);
}
}
//最后出栈的就是计算的结果
return Double.parseDouble(numStack.pop());
}
/**
* 获取运算符号的优先级
* @param symbol 传入的运算符号
*/
private static int getSymbolGread(String symbol){
int gread = 0;
switch (symbol) {
case "+":
case "-":
gread = 1;
break;
case "*":
case "/":
gread = 2;
default:
break;
}
return gread;
}
/**
* 判断传入的字符串是否为运算符号
* @param str 传入的字符串
*/
private static boolean isSymbol(String str) {
return str.equals("+") || str.equals("-") || str.equals("*") || str.equals("/");
}
}
网友评论