百度软件开发笔试大题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 }

 

posted @ 2015-09-18 00:49  CHEN0958  阅读(315)  评论(0编辑  收藏  举报