记录点滴
- 转换思路
//中缀表达式转后缀表达式步骤
/**
* 小括号()不算运算符优先级,
* 1.初始化两个栈,运算符栈s1,和存储中间结果的栈s2,
* 2.从左至右扫描中缀表达式
* 3.遇到数时,将其放入栈s2,
* 4.遇到运算符时,比较其与s1栈顶运算符的优先级:
* 4.1:如果s1为空,或为“(”左括号,直接放入栈s1
* 4.2:否则、若优先级比栈顶元素高,也存入栈s1中,
* 4.3:否则,将s1栈顶的元素取出,并存入s2中,再次转到步骤4中,与s1中新的栈顶元素比较
* 5.遇到括号时,
* 5.1:如果是左括号“( ” ,则直接存入s1中
* 5.2:如果是右括号“ ) ”,则依次取出s1中的元素,放入s2中,直到遇到左括号“( ”为止
* 6.重复步骤2-5知道遍历到表达式的最右端
* 7.将s1中的符号一次取出 并存入s2
* 8.依次取出s2中的元素,并输出,这时该结果的逆序,就是后缀表达式
*/
2 . 代码
public class PolanNotation {
public static void main(String[] args){
String input = "(11+5)*2-6+3";
System.out.println(transition(input)); //输出 后缀表达式
System.out.println(calculate(transition(input))); //根据后缀表达式输出最后结果
}
//前缀表达式转换后缀表达式的方法
public static ArrayList<String> transition(String input){
Stack<String> s1 = new Stack();//符号栈
Stack<String> s2 = new Stack();//数字栈
String ch = "";
for(int index = 0; index < input.length(); index++){
String temp = String.valueOf(input.substring(index, index + 1).charAt(0)); //取出单个字符并转换成String
if (temp.matches("\\d")){//匹配多位数字
if(index < input.length()-1){
if(String.valueOf(input.substring(index+1, index + 2).charAt(0)).matches("\\d")){
ch += temp;
}else {
ch += temp;
s2.push(ch);
ch = "";
}
}else {
ch += temp;
s2.push(ch);
}
}else if (temp.equals("(")){
s1.push(temp);
}else if (temp.equals(")")){
//则依次取出s1中的元素,放入s2中,直到遇到左括号“( ”为止
boolean flag = true;
while (flag){
if(s1.peek().equals("(")){
s1.pop();
flag = false;
}else {
s2.push(s1.pop());
}
}
}else {//剩下的就是运算符 + - * /了
/** 4.遇到运算符时,比较其与s1栈顶运算符的优先级:
* 4.1:如果s1为空,或为“(”左括号,直接放入栈s1
* 4.2:否则、若优先级比栈顶元素高,也存入栈s1中,
* 4.3:否则,将s1栈顶的元素取出,并存入s2中,再次转到步骤4中,与s1中新的栈顶元素比较
*/
if(s1.empty() || s1.peek().equals("(")){
s1.push(temp);
}else{
//判断优先级
boolean flag = true;
while (flag) {
if(!s1.empty()) {
int i = priority(s1.peek());
int j = priority(temp);
if (j > i) {
s1.push(temp);
flag = false;
} else {
s2.push(s1.pop());
}
}
s1.push(temp);
flag = false;
}
}
}
}
//第七步
while (!s1.empty()){
s2.push(s1.pop());
}
//第八步 依次取出s2中的元素,并输出,这时该结果的逆序,就是后缀表达式
ArrayList<String> arrayList = new ArrayList();
while (!s2.empty()){
arrayList.add(s2.pop());
}
Collections.reverse(arrayList);
return arrayList;
}
//运算符优先级方法
public static int priority(String oper){
if(oper.equals("*") || oper.equals("/")){
return 1;
}else if(oper.equals("+") || oper.equals("-")){
return 0;
}else {
return -1;
}
}
//根据后缀表达式求出最终结果
//计算,在栈中运算,每遇到一个运算符就取出两个数来计算,并将计算的值放入栈中
public static int calculate(ArrayList<String> ls){
Stack<String> stack = new Stack();
//遍历list
for(String a : ls){
if(a.matches("\\d+")){ //匹配多位数 \\d只匹配单个数字
stack.push(a);
}else {
int num1 = Integer.parseInt(stack.pop());
int num2 = Integer.parseInt(stack.pop());
int ele = 0;
if(a.equals("+")){
ele = num1 + num2;
}else if (a.equals("-")){
ele = num2 -num1;
}else if (a.equals("*")){
ele = num2 * num1;
}else if (a.equals("/")){
ele = num2 / num1;
}else {
throw new RuntimeException("传入的运算符有误");
}
stack.push(ele+"");
}
}
return Integer.parseInt(stack.pop());
}
}
来源:CSDN
作者:Jin的Xin
链接:https://blog.csdn.net/Z_dasheku/article/details/103601621