前缀表达式求解

问题描述:

  前缀表达式也叫波兰表达式,是将操作符前置的一种写法。

  中缀到前缀示例:

    ( 4 + 2 ) * ( 3 + 6 ) =>  * + 4 2 + 3 6

    (3 + 4 / 2) - 5 => - + 3 / 4 2 5

  默认按空格分隔,否则无法区分连续的数字。   

 

思路1(递归):

  1. 从左向右扫描

  2. 因为前缀表达式里都是双目运算符,且没有括号,所以遇到操作符可以递归求解,例如遇到乘号:

    case '*':

      return exp() * exp();

 

思路2(栈):

  1. 维护数字栈

  2. 从右向左扫描,遇到数字则入栈,遇到符号则出栈两个数字,计算后再入栈新数字,前缀表达式与后缀表达式求法对称,所以直接按后缀法相反方向求解即可。

 

代码1(递归):

 1 #include <string>
 2 #include <iostream>
 3 #include <sstream>
 4 
 5 using namespace std;
 6 
 7 //输入串
 8 string input_str = "* + 4.0 2.5 + 3 6";
 9 //偏移
10 int ind = 0;
11 
12 //得到下一个
13 string get_next()
14 {
15     string next;
16     for(; ind < input_str.size(); ind++)
17     {
18         if( input_str[ind] != ' ' )
19             next += input_str[ind];
20         else
21             break;
22     }
23     ind++;
24     return next;
25 }
26 
27 //递归计算:递归读取输入串
28 float cal_expression()
29 {
30     string next = get_next();
31     switch( next[0] )
32     {
33         case '*':
34             return cal_expression() * cal_expression();
35         case '/':
36             return cal_expression() / cal_expression();
37         case '+':
38             return cal_expression() + cal_expression();
39         case '-':
40             return cal_expression() - cal_expression();
41         default:
42             stringstream ss;
43             float num = 0.0;
44             ss << next;
45             ss >> num;
46             return num;
47     }
48 }
49 
50 int main()
51 {
52     cout << cal_expression() << endl;
53     return 0;
54 }

 

 代码2(栈):

 1 #include <string>
 2 #include <iostream>
 3 #include <sstream>
 4 #include <stack>
 5 
 6 using namespace std;
 7 
 8 string input_str = "* + 4.0 2.5 + 3 6";
 9 int rind = input_str.size() - 1;
10 stack<float> nums;
11 
12 //得到逆序第一个
13 string get_reverse_next()
14 {
15     string next = "";
16     for(; rind >= 0; rind--)
17     {
18         if( input_str[rind] != ' ' )
19             next = input_str[rind] + next;
20         else
21             break;
22     }
23     rind--;
24     return next;
25 }
26 
27 //弹出并根据exp操作符计算一次
28 float pop_cal_nums(string &exp)
29 {
30     float num1 = nums.top();
31     nums.pop();
32     float num2 = nums.top();
33     nums.pop();
34     switch( exp[0] )
35     {
36         case '*':
37             num2 *= num1;
38             break;
39         case '/':
40             num2 /= num1;
41             break;
42         case '+':
43             num2 += num1;
44             break;
45         case '-':
46             num2 -= num1;
47             break;
48     }
49     return num2;
50 }
51 
52 //使用栈计算
53 float cal_expression2() 
54 {
55     string next;
56     float res;
57     while( "" != (next = get_reverse_next()) )
58     {
59         if( ! isdigit(next[0]) )
60         {
61             res = pop_cal_nums(next);
62         }
63         else
64         {
65             stringstream ss;
66             ss << next;
67             ss >> res;
68         }
69         nums.push( res );
70     }
71     return res;
72 }
73 
74 int main()
75 {
76     cout << cal_expression2() << endl;
77     return 0;
78 }

 

 

转载请注明引用自:

  http://www.cnblogs.com/breakthings/p/4051773.html 

posted @ 2014-10-26 11:21  breakthings  阅读(2687)  评论(0编辑  收藏  举报