import java.util.*;
import java.util.Stack;
public class Three {
public static void main(String[] args){
Double result = Calculate.result("(3+1)+1/3+9");
System.out.println(result);
}
}
class Calculate {
//计算结果
public static Double result(String str) {
List<String> strList = strToStrList(str);
List<String> postList = toPostOrder(strList);
Double result = getResult(postList);
return result;
}
//将字符串转换为字符串List
private static List<String> strToStrList(String str) {
List<String> strList = new ArrayList<>();
int begin=0,end=0,post=0,i=0;
for (; i < str.length(); i++) {
if (str.charAt(i) == '+' || str.charAt(i) == '-' || str.charAt(i) == '*'
|| str.charAt(i) == '/' || str.charAt(i) == '(' || str.charAt(i) == ')') {
end = i;
if (begin < end) {
strList.add(str.substring(begin, end));
strList.add(str.substring(i,i+1));
}
//连续符号时
else {
strList.add(str.substring(i,i+1));
}
begin = i + 1;
}
}
//如果没有if包裹,当最后一个字符为操作符时,List末尾会添加一个空字符串
if (!"".equals(str.substring(begin, str.length()))){
strList.add(str.substring(begin, str.length()));
}
return strList;
}
/*
将中缀表达式转换为后缀表达式
*/
private static List<String> toPostOrder(List<String> strList) {
/*规则:
53 *1,运算数直接输出
54 *2,左括号压入堆栈
55 *3,右括号 将栈顶的运算符弹出并输出,括号出栈不输出
56 *4,运算符:
57 * 若优先级大于栈顶运算符,压入栈
58 * 若优先级小于或等于栈顶运算符,栈顶运算符弹出并输出,
59 * 继续和新栈顶比较,直到比栈顶运算符优先级大,将它压入栈
60 *5,对象处理完毕后,将栈中运算符弹出并输出
61 */
Stack<String> operStack = new Stack<>();
List<String> postList = new ArrayList<>();
for (int i = 0; i < strList.size(); i++) {
if (isOper(strList.get(i), i, strList)) {
//堆栈为空时操作符直接入栈
if (operStack.isEmpty()) {
operStack.push(strList.get(i));
} else {
//操作符为"("时直接入栈
if ("(".equals(strList.get(i))) {
operStack.push(strList.get(i));
} else if (")".equals(strList.get(i))) {
//操作符为")"时栈顶出栈并输出,直到遇到"(", "("出栈,")"不入栈
while (!"(".equals(operStack.peek())) {
postList.add(operStack.pop());
}
operStack.pop();
} else {
//其他操作符需要比较与栈顶元素的优先级
if ("(".equals(operStack.peek())) {
operStack.push(strList.get(i));
} else {
//优先级高,直接入栈
if (!operStack.isEmpty() && getPriority(strList.get(i)) > getPriority(operStack.peek())) {
operStack.push(strList.get(i));
} else {
if (!operStack.isEmpty() && getPriority(strList.get(i)) <= getPriority(operStack.peek()) && !"(".equals(operStack.peek())){
}
//优先级低或者相等,栈顶元素出栈,直到优先级比栈顶元素高
while (!operStack.isEmpty() && getPriority(strList.get(i)) <= getPriority(operStack.peek()) && !"(".equals(operStack.peek())) {
postList.add(operStack.pop());
}
if (operStack.isEmpty()) {
//若堆栈元素全部被弹出,直接入栈
operStack.push(strList.get(i));
} else if (getPriority(strList.get(i)) > getPriority(operStack.peek()) || "(".equals(operStack.peek())) {
//若优先级高,入栈
operStack.push(strList.get(i));
}
}
}
}
}
} else {
//操作数直接添加
if ("-".equals(strList.get(i))){
}else if (i >= 2 && "-".equals(strList.get(i - 1)) && "(".equals(strList.get(i - 2)) ) {
postList.add(strList.get(i - 1) + strList.get(i));
} else if (i == 1 && "-".equals(strList.get(i - 1))) {
postList.add(strList.get(i - 1) + strList.get(i));
} else {
postList.add(strList.get(i));
}
}
}
//最后将所有元素出栈
while (!operStack.isEmpty()) {
postList.add(operStack.pop());
}
return postList;
}
/**
* 计算后缀表达式
*/
private static double getResult(List<String> postList) {
/*规则:
157 *中缀表达式不用比较优先级
158 *将运算数入栈,每读到一个运算符
159 *就弹出栈顶的两个运算数,运算完毕后将结果压入栈
160 */
Stack<String> numStack = new Stack();
for(int i =0 ; i < postList.size(); i++) {
if (isNum(postList.get(i))) {
numStack.push(postList.get(i));
} else if (isOper(postList.get(i), i, postList)) {
if ("+".equals(postList.get(i))) {
Double num2 = Double.parseDouble(numStack.pop());
Double num1 = Double.parseDouble(numStack.pop());
Double result = num1 + num2;
numStack.push(result.toString());
} else if ("-".equals(postList.get(i))) {
Double num2 = Double.parseDouble(numStack.pop());
Double num1;
//能计算负数开头
if (numStack.isEmpty()) {
num1 = 0.0;
} else {
num1 = Double.parseDouble(numStack.pop());
}
Double result = num1 - num2;
numStack.push(result.toString());
} else if ("*".equals(postList.get(i))) {
Double num2 = Double.parseDouble(numStack.pop());
Double num1 = Double.parseDouble(numStack.pop());
Double result = num1 * num2;
numStack.push(result.toString());
} else if ("/".equals(postList.get(i))) {
Double num2 = Double.parseDouble(numStack.pop());
Double num1 = Double.parseDouble(numStack.pop());
Double result = num1 / num2;
numStack.push(result.toString());
}
}
}
return Double.parseDouble(numStack.pop());
}
/*
判断该字符串是否为操作符
*/
private static boolean isOper(String str, int i, List<String> stringList){
if("*".equals(str)|| "/".equals(str)||
"+".equals(str)||
"(".equals(str)|| ")".equals(str)){
return true;
} else if ("-".equals(str)) {
return !(i>=1 && "(".equals(stringList.get(i-1)));
}
else{
return false;
}
}
/*
判断该字符串是否为操作数
*/
private static boolean isNum(String str){
if("*".equals(str)|| "/".equals(str)||
"+".equals(str)|| "-".equals(str)||
"(".equals(str)|| ")".equals(str)){
return false;
}
else{
return true;
}
}
/*
得到操作符的优先级
*/
private static int getPriority(String c){
if("*".equals(c) || "/".equals(c)){
return 2;
} else if ("+".equals(c) || "-".equals(c)){
return 1;
} else {
return 999;
}
}
}
java实现计算器,能够进行负数运算
最新推荐文章于 2022-11-06 19:36:17 发布