算法思想:
(1)定义队列,保存后缀表达式。
(2)定义栈,暂存优先级由低到高的运算符。
(3)遍历中缀表达式,若是数字或小数点,则用len计数。若遇到运算符,则使用Arrays,copyOfRange(charArr,i-len,i)截取数字,保存至队列中。若遍历到的当前元素是(,则压入栈中。
(4)处理堆栈。若遍历到的当前元素是),则出栈所有元素放进队列中,直至遇到( 。若遍历到的当前元素的优先级≤栈顶元素,则出栈直至遍历到的当前元素的优先级>栈顶元素。
(5)若遍历到最后一位元素时必为数字,则使用Arrays,copyOfRange(charArr,i-len+1,i+1)截取数字。将栈中所有元素弹出至队列中。
public class InfixInToDuffix {
private static final Map<Character, Integer> basic = new HashMap<>();
static {
basic.put('-', 1);
basic.put('+', 1);
basic.put('*', 2);
basic.put('/', 2);
basic.put('(', 0);//在运算中()的优先级最高,但是此处因程序中需要 故设置为0
}
//将中缀表达式转换为后缀表达式
public String toSuffix(StringBuilder infix) {
List<String> queue = new ArrayList<>();
List<Character> stack = new ArrayList<>();
char[] charArr = infix.substring(0, infix.length()).trim().toCharArray();
String standard = "*/+-()";
char ch = '&';
int len = 0;
for (int i = 0; i < charArr.length; i++) {
ch = charArr[i];
if (Character.isDigit(ch)) {
len++;
} else if (ch == '.') {
len++;
} else if (standard.indexOf(ch) != -1) {
if (len > 0) {
queue.add(String.valueOf(Arrays.copyOfRange(charArr, i - len, i)));
len = 0;
}
if (ch == '(') {
stack.add(ch);
continue;
}
if (!stack.isEmpty()) {
int size = stack.size() - 1;
boolean flag = false;
while (size >= 0 && ch == ')' && stack.get(size) != '(') {
queue.add(String.valueOf(stack.remove(size)));
size--;
flag = true;
}
if (ch == ')' && stack.get(size) == '(') {
flag = true;
}
while (size >= 0 && !flag && basic.get(stack.get(size)) >= basic.get(ch)) {
queue.add(String.valueOf(stack.remove(size)));
size--;
}
}
if (ch != ')') {
stack.add(ch);
} else {
stack.remove(stack.size() - 1);
}
}
if (i == charArr.length - 1) { //如果已经走到了 中缀表达式的最后一位
if (len > 0) { //如果len>0 就截取数字
queue.add(String.valueOf(Arrays.copyOfRange(charArr, i - len + 1, i + 1)));
}
int size = stack.size() - 1; //size表示栈内最后一个元素下标
while (size >= 0) { //一直将栈内 符号全部出栈 并且加入队列中 【最终的后缀表达式是存放在队列中的,而栈内最后会被弹空】
queue.add(String.valueOf(stack.remove(size)));
size--;
}
}
}
String a = queue.toString();
return a.substring(1, a.length() - 1);
}
public String dealEquation(String equation) {
String[] arr = equation.split(", "); //根据, 拆分字符串
List<String> list = new ArrayList<String>(); //用于计算时 存储运算过程的集合【例如list中当前放置 100 20 5 / 则取出20/5 最终将结果4存入list 此时list中结果为 100 4 】
for (int i = 0; i < arr.length; i++) { //此处就是上面说的运算过程, 因为list.remove的缘故,所以取出最后一个数个最后两个数 都是size-2
int size = list.size();
switch (arr[i]) {
case "+":
double a = Double.parseDouble(list.remove(size - 2)) + Double.parseDouble(list.remove(size - 2));
list.add(String.valueOf(a));
break;
case "-":
double b = Double.parseDouble(list.remove(size - 2)) - Double.parseDouble(list.remove(size - 2));
list.add(String.valueOf(b));
break;
case "*":
double c = Double.parseDouble(list.remove(size - 2)) * Double.parseDouble(list.remove(size - 2));
list.add(String.valueOf(c));
break;
case "/":
double d = Double.parseDouble(list.remove(size - 2)) / Double.parseDouble(list.remove(size - 2));
list.add(String.valueOf(d));
break;
default:
list.add(arr[i]);
break;
}
}
return list.size() == 1 ? list.get(0) : "运算失败";
}
}