中序表达式转逆波兰表达式算法:
一、 将中缀表达式转换成后缀表达式算法:
1、从左至右扫描一中缀表达式。
2、若读取的是操作数,则判断该操作数的类型,并将该操作数存入操作数堆栈
3、若读取的是运算符
(1) 该运算符为左括号"(",则直接存入运算符堆栈。
(2) 该运算符为右括号")",则输出运算符堆栈中的运算符到操作数堆栈,直到遇到左括号为止。
(3) 该运算符为非括号运算符:
(a) 若运算符堆栈栈顶的运算符为括号,则直接存入运算符堆栈。
(b) 若比运算符堆栈栈顶的运算符优先级高或相等,则直接存入运算符堆栈。
(c) 若比运算符堆栈栈顶的运算符优先级低,则输出栈顶运算符到操作数堆栈,并将当前运算符压入运算符堆栈。
4、当表达式读取完成后运算符堆栈中尚有运算符时,则依序取出运算符到操作数堆栈,直到运算符堆栈为空。
public static void main(String[] args)
{
String a = "(1+2)*(3+4)";
//以下算法适用于10以内的数字
Stack<Character> stackOperator = new Stack<Character>();
char[] chars = a.toCharArray();
for (int i = 0; i < chars.length; i ++) {
char c = chars[i];
switch (c) {
case '+':
case '-':
case '*':
case '/':
while (!stackOperator.isEmpty() && compare(c, stackOperator.peek()) < 1)
{
System.out.print(stackOperator.pop());
}
stackOperator.push(c);
break;
case '(':
stackOperator.push(c);
break;
case ')':
while (stackOperator.peek() != '(') {
System.out.print(stackOperator.pop());
}
stackOperator.pop();
break;
default:
System.out.print(c);
break;
}
}
while (!stackOperator.isEmpty()) {
System.out.print(stackOperator.pop());
}
}
/** * 比较两个元素的优先级.
* * @param a 第一个元素 * @param b 第二个元素 * @return 如果第一个元素大于第二个, 则返回1, 相等则返回0, 小于则返回-1; */
public static int compare(char a, char b)
{
int qa = precedence(a);
int qb = precedence(b);
if (qa > qb)
return 1;
else if (qa == qb)
return 0;
else
return -1;
}
/** * 计算优先级 * @param a * @return 数字越大, 优先级越高 */
public static int precedence(char a) {
switch (a) {
case '+':
case '-':
return 1;
case '*':
case '/':
return 2;
default:
return 0;
}
}
}
二、逆波兰序列的求值过程
与中序序列转化的方式差不多,使用一个入栈的形式存储操作数序列,遇到操作符便进行运算,将结果入栈,然后最后出栈结果便可以了.
public static int Calculate(char[] input)
{
int length = input.length;
/*用来储存临时变量*/
int temp = 0;
Stack<Integer> stack = new Stack<Integer>();
for(int i= 0; i< length; i++)
{
temp = input[i];
switch(temp)
{
case '+':
stack.push(stack.pop()+stack.pop());
break;
case '-':
stack.push(-stack.pop()+stack.pop());
break;
case '*':
stack.push(stack.pop()*stack.pop());
break;
case '/':
int opNum1 = stack.pop();
int opNum2 = stack.pop();
stack.push(opNum2/opNum1);
break;
default:
stack.push(temp-48);
break;
}
}
return stack.pop();
}