前缀表达式求解
问题描述:
前缀表达式也叫波兰表达式,是将操作符前置的一种写法。
中缀到前缀示例:
( 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 }
转载请注明引用自: