百度软件开发笔试大题3
对表达式求值。已知运算符只有加减乘除,无负数,结果也不是负数。(类似逆波兰法的算法思路)
思想:对数字只要入栈就可以,需要时拿出来计算。对符号,有几种情况:
(1)新符号加入前符号栈中还没有符号,则直接入栈;
(2)新符号是加减运算,则将之前符号栈中的符号全部拿出来计算,每次消耗1个符号,2个数字,再将得到的结果压入数字栈;
(3)新符号是乘除,之前的符号也是乘除,则只需要消耗一个符号就行;
(4)新符号乘除,原来符号加减,则符号压栈即可。
Eg. 1+4*5+2*3,定义两个栈分别存数字和符号,叫numStack和sigStack。
1)数字"1"入栈numStack;
2)因栈中还没有符号,符号"+"进栈sigStack;
3)数字"4"进栈numStack;
4)"*"属于乘除,而栈顶是加减,所以直接入栈sigStack;
5)5直接进栈numStack;
6)新符号加减运算,意味着之前的运算都可以完成,顺序是:5,4分别出栈,*出栈,4*5=20入栈numStack,然后20,1分别出栈,+出栈,
1+20=21入栈numStack,从而numStack只留下21,sigStack为空,然后"+"入栈sigStack;
7)2入栈numStack;
8)新符号*,栈顶符号+,直接入栈;
9)3入栈。
至此所有元素已经处理完毕,接下来就可以消耗所有的符号了,顺序是:2,3出栈,*出栈,3*2=6入栈,6,21出栈,+出栈,21+6=27得到结果。
下面是Java实现代码:
1 package preTest; 2 3 import java.util.Scanner; 4 import java.util.Stack; 5 6 public class Main3 { 7 public static Stack sigStack = new Stack();//for char 8 public static Stack numStack = new Stack();//for int 9 10 public static void main(String[] args) { 11 Scanner in = new Scanner(System.in); 12 while(in.hasNext()){ 13 String str = in.nextLine(); 14 int result = cal(str); 15 System.out.println(result); 16 } 17 } 18 public static int cal(String str){ 19 sigStack.clear(); 20 numStack.clear(); 21 StringBuilder sb = new StringBuilder(); 22 int len = str.length(); 23 int result= 0; 24 //完成数字和符号的压栈 25 for(int i=0; i<len;i++){ 26 char c = str.charAt(i); 27 //数字 28 if(c>='0' && c <='9'){ 29 sb.append(c); 30 if(i==len-1){ 31 int x = Integer.parseInt((sb.toString())); 32 numStack.push(x); 33 } 34 }else{ 35 int x = Integer.parseInt((sb.toString())); 36 numStack.push(x); 37 sb.replace(0, sb.length(), ""); 38 if(sigStack.size() == 0){ 39 sigStack.push(c); 40 }else{ 41 char existed = (char)sigStack.peek(); 42 //如果已经压栈的符号优先级>=当前符号c,则完成压栈符号的操作 43 if(c=='+' || c=='-'){ 44 zhengli(); 45 sigStack.push(c); 46 //当两个都是乘除运算时 47 }else if(existed =='*' || existed == '/'){ 48 tinyAdjust(c); 49 }else{//新符号乘除,旧符号加减 50 sigStack.push(c); 51 } 52 } 53 } 54 } 55 //计算结果 56 zhengli(); 57 result = (int)numStack.pop(); 58 return result; 59 } 60 61 //简单加减乘除计算 62 public static int compute(int a, int b, char c){ 63 int result = 0; 64 switch(c){ 65 case '+': result = a+b; 66 break; 67 case '-': result = a-b; 68 break; 69 case '*': result = a*b; 70 break; 71 case '/': result = a/b; 72 break; 73 } 74 return result; 75 } 76 77 //完全消化已经压栈的符号,用于新符号是加减时 78 public static void zhengli(){ 79 while(sigStack.size() > 0){ 80 int a = (int)numStack.pop(); 81 int b = (int)numStack.pop(); 82 char c = (char)sigStack.pop(); 83 int x = compute(b,a,c); 84 numStack.push(x); 85 } 86 } 87 88 //消化一个符号,用于连续两个加减乘除符号出现时 89 public static void tinyAdjust(char c){ 90 int x1 = (int)numStack.pop(); 91 int x2 = (int)numStack.pop(); 92 int x3 = compute(x2, x1,(char)sigStack.pop()); 93 numStack.push(x3); 94 sigStack.push(c); 95 } 96 97 }