完整代码:
package LinkList.Stack.CalculateString;
import java.text.SimpleDateFormat;
import java.util.Scanner;
import java.util.Stack;
public class CaculateStringTest {
Stack<Integer> number = new Stack<>();
Stack<Character> operator = new Stack<>();
/**
* 计算运算符优先级
* @param operator
* @return 0代表优先级低,1代表优先级相等,2代表优先级高
*/
public int isPriority(char operator){
char prev = this.operator.peek();
if (prev == '+' || prev == '-'){
if (operator == '*' || operator == '/'){
return 2;
}else return 1;
}else if (prev == '*' || prev == '/'){
if (operator == '+' || operator == '-'){
return 0;
}else return 1;
}
throw new RuntimeException("未知错误");
}
/**
* 运算并返回计算结果(默认后一个数与前一个数运算)
* @param num1
* @param num2
* @param operator
* @return
*/
public int calculate(int num1,int num2,char operator) throws ArithmeticException{
switch (operator){
case '+'-> {
return num2+num1;
}
case '-'->{
return num2-num1;
}
case '*'->{
return num2*num1;
}
case '/'->{
return num2/num1;
}
}
throw new RuntimeException("未知错误");
}
public static void main(String[] args) {
CaculateStringTest caculateStringTest = new CaculateStringTest();
boolean isLoop = true;
Scanner scan = new Scanner(System.in);
while (isLoop){
System.out.println("-----------------------------------------------------------------------------------");
System.out.println("输入1,计算算式");
System.out.println("输入0,退出程序");
System.out.println("-----------------------------------------------------------------------------------");
String str = scan.next();
switch (str){
case "1" ->{
System.out.println("请输入算式(仅能计算整数,要求除法能整除):");
String word = scan.next();
long startTime = System.currentTimeMillis();
if (word.matches("^[^-+*/0-9]+$")){
//匹配到非法字符
System.out.println("请输入正确的表达式!");
continue;
}
char[] calculation = word.toCharArray();
//numStr 用于拼接多位数,当遍历到符号时再重置
String numStr = "";
for (int i = 0; i < calculation.length; i++) {
//如果是数字,直接入数栈
if (calculation[i] >= '0' && calculation[i] <= '9') {
//处理多位数
numStr += calculation[i];
//遍历到最后一个数字时,记得把最后一个数也压入数栈
if (i == calculation.length - 1) caculateStringTest.number.push(Integer.parseInt(numStr));
}else if(calculation[i] == '+' || calculation[i] == '-' || calculation[i] == '*' || calculation[i] == '/'){
//如果是运算符,符号栈若没元素直接入栈
//如果当前符号优先级小于等于符号栈中元素,先计算后将当前符号入栈
//如果当前符号优先级大于符号栈中元素,如果此时符号栈顶元素是'-',则需要反转符号栈顶元素且数栈中的栈顶元素符号修改为符号栈的栈顶元素
//如果此时符号栈顶元素是'+',则不需要反转符号栈顶元素且数栈需带符号,最后将当前符号放入符号栈栈顶
//将拼接好的numStr转成整数后压入数栈
caculateStringTest.number.push(Integer.parseInt(numStr));
//重置numStr
numStr = "";
//符号栈为空,直接将符号入符号栈
if (caculateStringTest.operator.isEmpty()){
caculateStringTest.operator.push(calculation[i]);
}else if (caculateStringTest.isPriority(calculation[i]) != 2){
//跟上一个运算符相比,当前运算符优先级低或者相等
//数栈弹出两个元素,符号栈弹出一个元素,计算后的结果压入数栈
try {
caculateStringTest.number.push(caculateStringTest.calculate(caculateStringTest.number.pop(),caculateStringTest.number.pop(),caculateStringTest.operator.pop()));
}catch (ArithmeticException e){
System.out.println("出现算数异常!程序退出.");
return;
}
//将当前符号压入符号栈
caculateStringTest.operator.push(calculation[i]);
} else if (caculateStringTest.isPriority(calculation[i]) == 2) {
//跟上一个运算符相比,当前运算符优先级高
//当上一个运算符是'-'
if (caculateStringTest.operator.peek() == '-'){
//先将符号栈弹出,然后反转成'+'压入符号栈
caculateStringTest.operator.pop();
caculateStringTest.operator.push('+');
//将数栈弹出,将弹出的数乘以-1处理后压回数栈
int pop = caculateStringTest.number.pop();
caculateStringTest.number.push((-1 * pop));
}
caculateStringTest.operator.push(calculation[i]);
}
}
}
//遍历完算式,计算数栈和符号栈剩下的运算
while (!caculateStringTest.operator.isEmpty()){
try {
caculateStringTest.number.push(caculateStringTest.calculate(caculateStringTest.number.pop(), caculateStringTest.number.pop(), caculateStringTest.operator.pop()));
}catch (ArithmeticException e){
System.out.println("出现算术异常!程序退出.");
return;
}
}
int result = caculateStringTest.number.pop();
System.out.printf("该计算结果为:[%d]",result);
long endTime = System.currentTimeMillis();
System.out.println();
System.out.println("计算花费时间: " + (endTime - startTime) + " ms");
}
case "0"-> isLoop = false;
}
}
}
}
测试图: