简介
来看这个中缀转后缀方法的,应该对什么是中缀什么是后缀应该有所了解,这里简单说一下不过多赘述了,介绍完就直接上代码了,不搞那么多花里胡哨的.
1.中缀表达式: 是符合人类阅读习惯的计算表达式,计算符在两个数字中间(负数比如-1就是0-1嘛,也可以看成计算符在两个数字之间),说白了就是计算式子,如:1+(2×3),就是中缀表达式.就是上学交的计算式的写法.
2. 后缀表达式: 是符合计算机计算习惯的一种表达式写法,因为计算机并不了解计算符的优先级,以及存在小括号的情况,这样计算机在计算表达式的值就非常的麻烦,不符合计算的习惯,而后缀表达式则是符合计算机习惯的一种表达式写法,如上面的中缀表达式1+(2×3),后缀表达式的写法就是123×+,这里只单独说明将中缀转后缀的方法,暂不讨论后缀表达式的计算方法.
话不多说,直接上方法.
方法
将中缀表达式装换为后缀表达式的方法
1.初始化两个栈:运算符栈operStack和储存中间结果的栈resStack;
2.从左至右扫描中缀表达式;
3.遇到操作数时,将其压resStack;
4.遇到运算符时,比较其与operStack栈顶运算符的优先级:
(1)如果operStack为空,或栈顶运算符为左括号“(”,则直接将此运算符入栈;
(2)否则,若优先级比栈顶运算符的高,也将运算符压入operStack;
(3)否则,将operStack栈顶的运算符弹出并压入到resStack中,再次转到(4-1)与operStack中新的栈顶运算符相比较;
5.遇到括号时:
(1) 如果是左括号“(”,则直接压入operStack
(2) 如果是右括号“)”,则依次弹出operStack栈顶的运算符,并压入resStack,直到遇到左括号为止,此时将这一对括号丢弃
6.重复步骤2至5,直到表达式的最右边
7.将operStack中剩余的运算符依次弹出并压入resStack
8.依次弹出resStack中的元素并输出,结果的逆序即为中缀表达式对应的后缀表达式
注意:
@param infix 代表中缀表达式的list集合,之所以用list是为了方便多位数的查找,
如果1+12,在list中就是第一个就是[1,+,12],多位数需要看成是一个整体
如果是char数组在逐个判断时不方便判断多位数;
@return 返回后缀表达式的list集合
代码
/**
* 将中缀表达式装换为后缀表达式的方法
* 1.初始化两个栈:运算符栈operStack和储存中间结果的栈resStack;
* 2.从左至右扫描中缀表达式;
* 3.遇到操作数时,将其压resStack;
* 4.遇到运算符时,比较其与operStack栈顶运算符的优先级:
* 4.1如果operStack为空,或栈顶运算符为左括号“(”,则直接将此运算符入栈;
* 4.2否则,若优先级比栈顶运算符的高,也将运算符压入operStack;
* 4.3否则,将operStack栈顶的运算符弹出并压入到resStack中,再次转到(4-1)与operStack中新的栈顶运算符相比较;
* 5.遇到括号时:
* (1) 如果是左括号“(”,则直接压入operStack
* (2) 如果是右括号“)”,则依次弹出operStack栈顶的运算符,并压入resStack,直到遇到左括号为止,此时将这一对括号丢弃
* 6.重复步骤2至5,直到表达式的最右边
* 7.将operStack中剩余的运算符依次弹出并压入resStack
* 8.依次弹出resStack中的元素并输出,结果的逆序即为中缀表达式对应的后缀表达式
* @param infix 代表中缀表达式的list集合,之所以用list是为了方便多位数的查找,
* 如果1+12,在list中就是第一个就是[1,+,12],多位数需要看成是一个整体
* 如果是char数组在逐个判断时不方便判断多位数;
* @return 返回后缀表达式的list集合
*/
public List<String> transSuffix(List<String> infix){
Stack<String> operStack = new Stack<>();
Stack<String> resStack = new Stack<>();
//循环遍历中缀表达式,value代表当前的字符
for(String value : infix){
//设置开关控制下面else中的循环
boolean flag = true;
//如果是数字就直接加到res中
// \\d+是正则表达式,代表任意数字
if(value.matches("\\d+")){
resStack.push