用的ArrayList,当栈当数组随便了
详情看注释
package _01Unitary;
import java.util.ArrayList;
import java.util.Scanner;
public class _04Computer {
public static void main(String[] args) {
String ch = new Scanner(System.in).nextLine();//输入字符
ArrayList<String> h = new ArrayList<>(), z = new ArrayList<>(), arrayList = new ArrayList<>();//h为后缀表达式,z为操作符栈,arrayList为表达式String分离后的接收List
fenLi(ch, arrayList);//分离数字与操作符
for (String str : arrayList) {
if (!isF(str)) //是数则加入后缀
h.add(str);
else if (str.equals("("))//是"("直接入栈
z.add(str);
else if (str.equals(")")) {//是")"则弹出操作符遇"("停止
for (int j = z.size() - 1; j >= 0; j--) {
if (z.get(z.size() - 1).equals("(")) break;
h.add(z.remove(z.size() - 1));
}
z.remove(z.size() - 1);//"("不加入后缀表达式
} else {
for (int j = z.size() - 1; j >= 0; j--) {/*每次遇到操作符会坚持栈里有没有优先级大于或等于自身的,有则弹出*/
if (z.get(j).equals("(")) break;
if ((youXianJi(z.get(j)) - youXianJi(str)) >= 0 ? true : false)
h.add(z.remove(j));
}
z.add(str);//将此操作符入栈
}
}
for (int j = z.size() - 1; j >= 0; j--)
h.add(z.remove(j));//表达式遍历完了后将所有栈内操作符出栈加到后缀表达式中
System.out.println(suan(h));
}
public static void fenLi(String ch, ArrayList<String> arrayList) {//分离最初字符串
StringBuilder sb = new StringBuilder();
for (int i = 0; i < ch.length(); i++) {
if (isS(ch.charAt(i)))
sb.append(ch.charAt(i));
else {
if (!sb.isEmpty()) {
arrayList.add(sb.toString());
sb = new StringBuilder();
}
arrayList.add(String.valueOf(ch.charAt(i)));
}
}
if (!sb.isEmpty()) {
arrayList.add(sb.toString());
}
}
public static boolean isS(char a) {
if (a == '+' || a == '-' || a == '*' || a == '/' || a == '(' || a == ')')
return false;
else return true;
}//判断是否为数字,形参为char情况
public static boolean isF(String a) {
if (a.equals("+") || a.equals("-") || a.equals("*") || a.equals("/") || a.equals("(") || a.equals(")"))
return true;
else return false;
}/*判断是否为符号,形参为String的情况。ps:没办法只能写两个,一个是String遍历分离要用,一个是后面遍历arrayList<String>时要用*/
public static int youXianJi(String ch) {//返回优先级
int a = 0;
switch (ch) {
case "+":
case "-":
a = 1;
break;
case "*":
case "/":
a = 2;
break;
}
return a;
}
public static Double suan(ArrayList<String> list) {//算后缀表达式
ArrayList<String> t = new ArrayList<>();//来一个数字栈
for (String i : list) {
if (!isF(i))
t.add(i);
else {
t.add(js(i, t.remove(t.size() - 1), t.remove(t.size() - 1)));/*注意形参为啥这样写嘿嘿*/
}
}
return Double.parseDouble(t.get(0));
}
public static String js(String i, String s1, String s2) {/*后缀表达式弹出操作符时数字栈的顶的计算*/
Double a = 0.0;
switch (i) {
case "+":
a = Double.parseDouble(s2) + Double.parseDouble(s1);
break;
case "-":
a = Double.parseDouble(s2) - Double.parseDouble(s1);
break;
case "*":
a = Double.parseDouble(s2) * Double.parseDouble(s1);
break;
case "/":
a = Double.parseDouble(s2) / Double.parseDouble(s1);
break;
}
return String.valueOf(a);
}
}