算法训练 表达式计算
时间限制:1.0s 内存限制:256.0MB
问题描述
输入一个只包含加减乖除和括号的合法表达式,求表达式的值。其中除表示整除。
输入格式
输入一行,包含一个表达式。
输出格式
输出这个表达式的值。
样例输入
1-2+3*(4-5)
样例输出
-4
数据规模和约定
表达式长度不超过100,表达式运算合法且运算过程都在int内进行。
这题就是栈的应用的基础题目,虽然基础但是写起来还是挺麻烦的:
1,这题考察的是中缀表达式的计算,符号栈,数字栈,结合运算符的优先级就能写出来
2,具体运算流程课本上很详细。
3,模拟要细心一些
4,高级点的做法,结合编译原理或许代码量还能少很多。
import java.util.Scanner; import java.util.Stack; public class Main { public static void main(String[] args) { Scanner in = new Scanner(System.in); //1-2+3*(4-5) while(in.hasNext()){ String str = in.next() ; str="#"+str+"#" ; //System.out.println(str); Stack<Integer> ss = new Stack<Integer>() ; Stack op = new Stack() ; op.clear(); ss.clear(); for(int i=0;i<str.length();i++){ int pre = 0 ; if(str.charAt(i)>='0'&&str.charAt(i)<='9'){///读到数字 pre = i ; for(int j=i;j<str.length();j++){ if(str.charAt(j)<'0'||str.charAt(j)>'9'){ i=j ; break ; } if(str.charAt(j)>='0'&&str.charAt(j)<='9'&&j==str.length()-1){ i=str.length() ; break ; } } //System.out.println(pre+","+i); int x = Integer.valueOf(str.substring(pre, i)) ; //System.out.println(x); i--; ///压入数字栈 ss.push(x) ; }else{//读到符号 if(str.charAt(i)=='('||(str.charAt(i)=='#'&&op.size()==0)){///左括号和标识直接进入符号栈 op.push(str.charAt(i)) ; //System.out.println("begin"); continue ; } if((op.peek().equals('(')||op.peek().equals('#'))&&(str.charAt(i)=='+'||str.charAt(i)=='-'||str.charAt(i)=='*'||str.charAt(i)=='/')){//第一个运算符压入符号栈 op.push(str.charAt(i)) ; //System.out.println("first"); continue ; } if(str.charAt(i)==')'){///右括号 int temp =0 ; while(!op.peek().equals('(')){ int b = (int)ss.pop() ; int a = (int)ss.pop() ; if(op.peek().equals('+')){ temp = a+b; }else if(op.peek().equals('-')){ temp = a-b; }else if(op.peek().equals('*')){ temp = a*b; }else { temp = a/b; } op.pop(); ss.push(temp) ; } op.pop() ; continue ; } if(str.charAt(i)=='#'){///结尾 int temp =0 ; //System.out.println(op.peek()); while(!op.peek().equals('#')){ int b = (int)ss.pop() ; int a = (int)ss.pop() ; if(op.peek().equals('+')){ temp = a+b; }else if(op.peek().equals('-')){ temp = a-b; }else if(op.peek().equals('*')){ temp = a*b; }else{ temp = a/b; } op.pop(); ss.push(temp) ; } op.pop() ; continue ; } ///+-同级之间相遇,前面的算一下就ok了 if((str.charAt(i)=='+'||str.charAt(i)=='-')&&(op.peek().equals('+')||op.peek().equals('-'))){ int temp=0; int b = (int)ss.pop() ; int a = (int)ss.pop() ; if(op.peek().equals('+')){ temp = a+b; }else{ temp = a-b; } //System.out.println("temp="+temp); op.pop(); ss.push(temp) ; op.push(str.charAt(i)); continue ; } /// */同级之间相遇 if((str.charAt(i)=='*'||str.charAt(i)=='/')&&(op.peek().equals('*')||op.peek().equals('/'))){ int temp=0; int b = (int)ss.pop() ; int a = (int)ss.pop() ; if(op.peek().equals('*')){ temp = a*b; }else{ temp = a/b; } op.pop(); ss.push(temp) ; op.push(str.charAt(i)); continue ; } //+-遇到*/ if((str.charAt(i)=='+'||str.charAt(i)=='-')&&(op.peek().equals('*')||op.peek().equals('/'))){ int temp=0; int b = (int)ss.pop() ; int a = (int)ss.pop() ; if(op.peek().equals('*')){ temp = a*b; }else{ temp = a/b; } op.pop() ; ss.push(temp) ; op.push(str.charAt(i)); continue ; } ///*/遇到+- if((str.charAt(i)=='*'||str.charAt(i)=='/')&&(op.peek().equals('+')||op.peek().equals('-'))){ op.push(str.charAt(i)); continue ; } } } System.out.println(ss.peek()); } } }