利用数据结构中栈的知识点写了一个四则运算的程序,可用计算包含±*/()的简单四则运算表达式的值,代码如下:
package com.corecmd.tcloud.tcgateway.utils;
import java.util.*;
import java.util.regex.Pattern;
/**
* @author : TianShaoJiao
* @version : 1.0
* @apiNote :
* @date :2021/4/20
**/
public class StackDemo {
private static final Pattern PATTERN = Pattern.compile("[\\d\\+\\-*/()]+");
private static final String FORMULACHARS = "+-*/()";
private static Map<String,Integer> opParamsLevel = null;
public static void main(String[] args) {
initFormulaOpCharLevel();
System.out.println("请输入四则运算等式,运算符包括:+ - * / ( ),按回车键结束;输入exit则结束程序");
String formula = getFormula();
while (!"exit".equalsIgnoreCase(formula)){
if (null == formula){
formula = getFormula();
continue;
}
//取得操作符及操作数
List<String> formulaStrs = getFormulaCharacters(formula);
//System.out.println("运算表达式:"+formulaStrs.toString());
//取得后缀表达式
List<String> rpn = getRpn(formulaStrs);
//System.out.println("rpn="+rpn.toString());
//计算表达式结果
int result = calculateFormula(rpn);
System.out.println(formula+"="+result);
System.out.println("===========================");
System.out.println("继续输入四则运算等式...");
formula = getFormula();
}
System.out.println("bye...");
}
private static int calculateFormula(List<String> rpn) {
Deque<String> stack = new LinkedList<String>();
for (String rpnStr:rpn) {
if (FORMULACHARS.contains(rpnStr)){
//取出两个操作数
int rightNumber = Integer.parseInt(stack.pop());
int leftNumber = Integer.parseInt(stack.pop());
//判断是+- 或者 */
stack.push(calc(leftNumber,rightNumber,rpnStr));
} else {
stack.push(rpnStr);
}
}
//得到最后的结果
return Integer.parseInt(stack.pop());
}
/**
* 根据符号计算两个数的操作结果
* @param leftNumber
* @param rightNumber
* @param rpnStr
* @return
*/
private static String calc(int leftNumber, int rightNumber, String rpnStr) {
int result = 0;
switch (rpnStr){
case "+":
result = (leftNumber + rightNumber);
break;
case "-":
result = (leftNumber - rightNumber);
break;
case "*":
result = (leftNumber * rightNumber);
break;
case "/":
result = (leftNumber / rightNumber);
break;
default:
result = 0;
}
return String.valueOf(result);
}
/**
* 初始化运算符优先级
* @return
*/
private static void initFormulaOpCharLevel(){
opParamsLevel = new HashMap<String,Integer>();
opParamsLevel.put("+",1);
opParamsLevel.put("-",1);
opParamsLevel.put("*",2);
opParamsLevel.put("/",2);
opParamsLevel.put("(",0);
opParamsLevel.put(")",0);
}
/**
* 取得后缀表达式
*/
private static List<String> getRpn(List<String> formulaStrs){
List<String> result = new ArrayList<String>();
Deque<String> stack = new LinkedList<String>();
for (int i = 0; i < formulaStrs.size(); i++) {
String currentStr = formulaStrs.get(i);
//判断是否是符号
if (FORMULACHARS.contains(currentStr)){
String top = stack.peek();
if (null == top){
stack.push(currentStr);
continue;
}
int topLevel = opParamsLevel.get(top);
int currentLevel = opParamsLevel.get(currentStr);
//1、如果当前符号优先级低于栈顶符号,则栈顶符号出栈,当前符号进栈
if ("(".equals(currentStr)){
stack.push(currentStr);
}
else if (!")".equals(currentStr) && currentLevel > topLevel){
stack.push(currentStr);
} else if (!")".equals(currentStr) && currentLevel <= topLevel){
//将小于等于当前操作符优先级的全部出栈
while (true){
result.add(stack.pop());
String nextTop = stack.peek();
if (nextTop == null || currentLevel > opParamsLevel.get(nextTop)){
break;
}
}
stack.push(currentStr);
} else {
//找到栈中的"("
while (true){
String topStr = stack.pop();
if (!"(".equals(topStr)){
result.add(topStr);
} else {
break;
}
}
}
} else {
result.add(currentStr);
}
//到最后一个运算符,栈中数据全出栈
if (i == formulaStrs.size() - 1){
while (stack.size() > 0){
result.add(stack.pop());
}
}
}
return result;
}
/**
* 取得操作符及操作数
*/
private static List<String> getFormulaCharacters(String formula) {
List<String> result = new ArrayList<>();
int markUp = 0;
char []chars = formula.toCharArray();
for (int i = 0; i < chars.length; i++){
String currentChar = String.valueOf(chars[i]);
if ("(".equals(currentChar)){
result.add(currentChar);
markUp = i + 1;
}
else if (!"(".contains(currentChar) && FORMULACHARS.contains(currentChar)){
//将markUp到i的符号作为一个数
if (!")".equals(String.valueOf(chars[i-1]))){
StringBuilder sb = new StringBuilder();
for(int j = markUp;j <= i - 1; j++){
sb.append(chars[j]);
}
result.add(sb.toString());
}
result.add(String.valueOf(chars[i]));
markUp = i + 1;
}
if (i == chars.length - 1){
//末尾时
if (!")".equals(String.valueOf(chars[i]))){
StringBuilder sb2 = new StringBuilder();
for(int j = markUp;j <= i; j++){
sb2.append(chars[j]);
}
result.add(sb2.toString());
markUp = i;
}
}
}
return result;
}
private static String getFormula(){
Scanner scanner = new Scanner(System.in);
String formula = scanner.next().trim();
if (PATTERN.matcher(formula).matches()){
return formula;
}
System.out.println("包含不合法字符,请重新输入");
return null;
}
}