58同城1012笔试第二题
示例1
输入
“exp1 & (exp2|exp3)/!exp4”
输出
“exp1 exp2 exp3| & exp4 !”
思路与代码
这个代码的核心思想是通过栈来处理不同操作符的优先级和括号的嵌套,将中缀表达式转换为后缀表达式,以便更容易进行计算。
遍历输入的中缀表达式字符串,根据不同情况执行以下操作:
如果是操作符(如’!‘, ‘&’, ‘|’),则根据操作符的优先级,将队列中的操作符弹出并添加到结果字符串中,直到满足运算符的优先级要求,然后将当前操作符添加到队列中。
如果是左括号’(‘,直接添加到队列中。
如果是右括号’)‘,则弹出队列中的操作符并添加到结果字符串,直到遇到左括号’(‘。
如果是空格字符’ ',跳过。
否则,将操作数添加到结果字符串中。
最后,将队列中剩余的操作符依次弹出并添加到结果字符串中。
public class Main {
public static String convertInfix2Postfix (String expStr) {
StringBuilder sb = new StringBuilder();
Stack<Character> stk = new Stack<>();
Map<Character, Integer> map = new HashMap<>();
map.put('!', 5);
map.put('&', 4);
map.put('|', 3);
Set<Character> set = new HashSet<>();
set.add('!');
set.add('&');
set.add('|');
set.add('(');
set.add(')');
int N = expStr.length();
for(int i=0; i<N; ++i){
char ch = expStr.charAt(i);
if(map.containsKey(ch)){
while(!stk.isEmpty() && stk.peek()!='('&& map.get(ch) <= map.get(stk.peek()) ){
sb.append(stk.pop());
sb.append(' ');
}
stk.push(ch);
}else if (ch == '('){
stk.push(ch);
}else if (ch == ')'){
while(stk.peek()!='('){
sb.append(stk.pop());
sb.append(' ');
}
stk.pop();
}else if (ch == ' '){
continue;
}else {
int j = i;
while(j<N && !set.contains(expStr.charAt(j))){
if(expStr.charAt(j) != ' ')
sb.append(expStr.charAt(j));
++j;
}
sb.append(' ');
i = j-1;
}
}
while(!stk.isEmpty()){
sb.append(stk.pop());
sb.append(' ');
}
sb.deleteCharAt(sb.length()-1);
return sb.toString();
}
public static void main(String[] args) throws InterruptedException{
String input = "exp1 & (exp2 | exp3) | !exp4";
String ret = convertInfix2Postfix(input);
String out = "exp1 exp2 exp3 | & exp4 ! |";
System.out.println(ret);
System.out.println(out.equals(ret));
}
}
思路:
中缀表达式转后缀表达式,根节点其实就是运算符。利用栈来模拟,算法的具体原理还没想好解释。代码实现先贴着。