该片文章解决了 多位数、多括号、负数等问题,喜欢可以仔细的看
中缀转后缀思路
后缀表达式运算思路
代码
public class InfixConverSuffixExpressionDemo {
public static void main(String[] args) {
Queue<String> strings = SuffixExpression.infixConverSuffixExpression("-20* 5 - 20*4+1");
System.out.println("结果==:"+SuffixExpression.calculateSuffixExpression(strings));
}
}
//后缀表达式类
class SuffixExpression{
//创建一个中缀表达式转后缀表达式
//思路使用栈和队列 创建一个内容队列里面存储的是中转后的一个表达式形式 栈是存储对应的符号内容
public static Queue<String> infixConverSuffixExpression(String expression){
//将表达式转换成字符数组
char[] expressionArr=expression.toCharArray();
//创建一个存储符号栈对象
Stack<Character> symbolStack=new Stack<>();
//创建一个内容队列里面存储的就是数组加运算符的后缀表达式格式
Queue<String> contentQueue=new ConcurrentLinkedQueue<>();
//创建一个拼接数组变量
String numberLinked="";
for(int index=0;index<expressionArr.length;index++){
//获取当前字符
Character currentChar=expressionArr[index];
if(currentChar==' ')continue;
//判断是否是运算符
if(isSymbol(currentChar+"")){
//判断当前运算符时候是减号
if(currentChar=='-'&&index==0||!isNumeric(expressionArr[index-1]+"")&&expressionArr[index-1]!=')'&&expressionArr[index-1]!=' '){
numberLinked+=currentChar;
}else{
//判断当前符号与符号栈栈顶元素做比较
while(!symbolStack.isEmpty()){
if(symbolLevel(currentChar)<=symbolLevel(symbolStack.peek())){
contentQueue.add(symbolStack.pop()+"");
}else{
break;
}
}
symbolStack.push(currentChar);
}
}
//判断是否是括号
else if(currentChar=='('|| currentChar==')'){
if(currentChar=='('){
//将左括号存入到符号栈中
symbolStack.push(currentChar);
}else{
//依次取 出符号栈内容直到取出的内容是左括号位置
while(!symbolStack.isEmpty()){
char currPopChar=symbolStack.pop();
if(currPopChar!='('){
contentQueue.add(currPopChar+"");
}else{
break;
}
}
}
}else{
//将当前字符拼接在numberLinked上
numberLinked+=currentChar;
//判断当前字符是否是最后一个
if(index>=expressionArr.length-1){
//将当前字符串数组存储到内容队列中
contentQueue.add(numberLinked);
}else{
//判断当前索引的下一个索引元素是否是非数值
if(!isNumeric(expressionArr[index+1]+"")){
contentQueue.add(numberLinked);
numberLinked="";
}
}
}
}
//将多余符号栈内容依次取出存储到内容队列中
while(!symbolStack.isEmpty()){
contentQueue.add(symbolStack.pop()+"");
}
return contentQueue;
}
//计算后缀表达式
public static Integer calculateSuffixExpression(Queue<String> contentQueue){
//创建一个数值栈用于存储数值
Stack<Integer> numberStack=new Stack<>();
//遍历内容队列
while(!contentQueue.isEmpty()){
String currentContent=contentQueue.poll();
if(isSymbol(currentContent)){
//获取数值栈栈顶元素和次顶元素
int num1=numberStack.pop();
int num2=numberStack.pop();
numberStack.push(calculate(num1,num2,currentContent.toCharArray()[0]));
}else{
//将数组内容存储到数值栈中
numberStack.push(Integer.parseInt(currentContent));
}
}
return numberStack.pop();
}
public static boolean isSymbol(String ch){
return ch.equals("+") || ch.equals("-") || ch.equals("*") || ch.equals("/");
}
/**
* 判断是否为数字(正负数都行)
* @param str 需要验证的字符串
* @return
*/
public static boolean isNumeric(String str){
Pattern pattern = Pattern.compile("^-?\\d+(\\.\\d+)?$");
Matcher isNum = pattern.matcher(str);
if( !isNum.matches() ){
return false;
}
return true;
}
/******************************
* 作者: 刘梓江
* 时间: 2019/12/12 19:58
* 描述: 判断符号等级 等级越大 数值就越大
******************************/
public static int symbolLevel(int ch){
if(ch=='+'|| ch=='-'){
return 1;
}else if(ch=='*'|| ch=='/'){
return 2;
}else{
return -1;
}
}
/******************************
* 作者: 刘梓江
* 时间: 2019/12/12 9:25
* 描述: 计算2个数值
******************************/
public static int calculate(int num1,int num2,Character ch){
switch (ch){
case '+':
return num2+num1; //由于是栈特点所以最前面的数取的时候最末尾
case '-':
return num2-num1; //由于是栈特点所以最前面的数取的时候最末尾
case '*':
return num2*num1; //由于是栈特点所以最前面的数取的时候最末尾
case '/':
return num2/num1; //由于是栈特点所以最前面的数取的时候最末尾
default:
return -1;
}
}
}