栈的应用-表达式求值
1.概念:
表达式包括 { 前缀表达式(波兰式)、中缀表达式、后缀表达式(逆波兰式)}
例如:(a+b)*(a-b)
前缀表达式:*+ab-ab
中缀表达式:(a+b)*(a-b)
后缀表达式:ab+ab-*
高级语言中采用自然语言的中缀表达式,但是计算机对中缀表达式的处理是非常困难的,而对后缀或前缀表达式则显得非常简单
后缀表达式的特点:
1.在后缀表达式中,变量(操作数)出现的顺序与中缀表达式出现的顺序相同
2.后缀表达式中不需要括号规定计算顺序,而由运算符的位置来确定运算顺序
2.中缀表达式转后缀表达式
例:(a+b)*(a-b) -> ab+ab-*
算法:
1.对中缀表达式从左至右依次扫描,由于操作数的顺序不变,当遇到操作数的时候直接输出;
2.为调整运算顺序,设立一个栈用以保存操作符,扫描到操作符时,将操作符压入栈中
进栈的原则是保持栈顶的操作符的优先级要高于栈中其他操作符的优先级,否则,将栈顶的操作符依次出栈并输出,直到满足要求为止
3.遇到"("时进栈,当遇到")"时,出栈输出,直到遇到")"为止
3.由后缀表达式计算表达式的值
算法:
对后缀表达式从左至右依次扫描,遇到操作数时,将操作数进栈保存
当遇到操作符时,从栈中弹出两个操作数并进行运算,将运算的结果进栈保存;直到表达式结束,栈中唯一的元素即为表达式的值
代码:
只支持 + - / * ( )的大于 0 小于 10 的整数运算
如果想看更加完整的代码请看文章:http://www.jiajiajia.club/weblog/blog/artical/28
package problem;
import java.util.Stack;
/**
* 表达式计算
* @author LENOVO
*
*/
public class Test1 {
public static void main(String[] args) {
String mid="(4+2)*(2-1)+8+(1*2)";
String sub=midToSub(mid);
System.out.println(sub);
System.err.println(count(sub));
}
/**
* 中序表达式转后续表达式
* @return
*/
public static String midToSub(String mid) {
Stack<Character> stack=new Stack<>();
String sub="";
char c;
for(int i=0;i<mid.length();i++) {
c=mid.charAt(i);
if(c>='0'&&c<='9') {//操作数
sub+=c;
}else{//操作符
if(c=='*'||c=='/') {//*/
stack.push(c);
}else if(c=='+'||c=='-') {//+-
while(!stack.empty()&&(stack.peek()=='*'||stack.peek()=='/')) {
sub+=stack.pop();
}
stack.add(c);
}else if(c=='(') {//(
stack.add(c);
}else if(c==')'){//)
while(!stack.empty()&&stack.peek()!='(') {
sub+=stack.pop();
}
stack.pop();
}
}
}
while(!stack.empty()) {//所有的元素出栈
sub+=stack.pop();
}
return sub;
}
public static int count(String sub) {
Stack<Integer> stack=new Stack<>();
Character c;
Integer a;
Integer b;
for(int i=0;i<sub.length();i++) {
c=sub.charAt(i);
if(c>='0'&&c<='9') {
stack.add(Integer.valueOf(c.toString()));
}else{
if(c=='+') {
stack.add(stack.pop()+stack.pop());
}else if(c=='-') {
a=stack.pop();
b=stack.pop();
stack.add(b-a);
}else if(c=='*') {
stack.add(stack.pop()*stack.pop());
}else{
a=stack.pop();
b=stack.pop();
stack.add(b/a);
}
}
}
return stack.pop();
}
}
