首页 > 代码库 > 表达式求值(只包括小括号)
表达式求值(只包括小括号)
表达式求值
前缀式:就是将操作符放到数值的前面;如:a+b : +ab;
中缀式:就是将操作符放在数值中间,其实就是我们平时生活中所写的正常的表达式。如:a+b;
后缀式:就是将操作符放在数值的后面,比如:a+b:——ab+.
对于表达式求值,最简单的当然是对后缀表达式(也称为逆波兰式)进行求值了。
而我们生活中所写的运算表达式,一般都是中缀表达式。但是我们计算的时候用到的却是后缀表达式。这就需要我们首先将中缀表达式转换为后缀表达式,然后再进行运算了。
1、中缀式转换为后缀式
下面是将中缀式(常见运算式)转换为后缀式的算法(该算法只能处理只包含“(”和“)”的运算符):
栈底放‘#’,从左至右逐字读取中缀式:
a.当当前字符为数字时,直接输出;
b.当当前字符为"("时,将其压栈;
c.当当前字符为")"时,则弹出堆栈中最上的"("之前的所有运算符并输出,然后删除堆栈中的"(" ;
d.当当前字符为运算符时,则依次弹出堆栈中优先级大于等于当前运算符的(到"("之前为止),输出,再将当前运算符压栈;
e.当为"#"时,弹出所有栈中的内容输出
中缀式:a*(b+c)/d+e
后缀式:abc+*d/e+
2、后缀式计算
计算后缀表达式的具体算法如下:
首先定义一个栈stk,用于存放计算结果。
a.当前元素为数值,直接入栈;
b.如果当前元素是运算符,则将stk中栈顶的两个元素弹出:m,n;
c.根据运算符类别(+、-、*、/)计算t = n op m;(m 是第一个弹出栈的元素);
d.将计算的结果t重新压入栈stk中。
e.当后缀表达式还未结束,转到a继续执行,否则计算结束。stk此时的栈顶元素即是最后的计算结果。
具体的实现代码如下所示:
1 #include <iostream> 2 #include <fstream> 3 #include <sstream> 4 #include <stack> 5 #include <vector> 6 #include <map> 7 #include <string> 8 #include <algorithm> 9 using namespace std; 10 11 map<char,int> priority; 12 13 void setPriority() 14 { 15 priority[‘-‘] = 1; 16 priority[‘+‘] = 1; 17 priority[‘*‘] = 2; 18 priority[‘/‘] = 2; 19 } 20 21 void InfixToPostfix(const string &src,vector<char> &exp) 22 { 23 int i,n; 24 stack<char> op; 25 26 n = src.size(); 27 for (i = 0; i < n; i++) 28 { 29 switch(src[i]) 30 { 31 case ‘(‘: 32 op.push(src[i]); 33 break; 34 case ‘)‘: 35 while (op.size() != 0 && op.top() != ‘(‘) 36 { 37 exp.push_back(op.top()); 38 op.pop(); 39 } 40 op.pop(); 41 break; 42 case ‘+‘: 43 case ‘-‘: 44 case ‘*‘: 45 case ‘/‘: 46 while (op.size() != 0 && priority[op.top()] >= priority[src[i]]) 47 { 48 exp.push_back(op.top()); 49 op.pop(); 50 } 51 52 op.push(src[i]); 53 break; 54 case ‘ ‘: 55 break; 56 default: 57 while (isdigit(src[i]) && i<n) 58 { 59 exp.push_back(src[i]); 60 i++; 61 } 62 i--; 63 exp.push_back(‘#‘); 64 } 65 } 66 while (op.size() !=0 ) 67 { 68 exp.push_back(op.top()); 69 op.pop(); 70 } 71 } 72 73 void displayExp(vector<char> &src) 74 { 75 int i,n; 76 n = src.size(); 77 for (i = 0; i < n; i++) 78 { 79 cout<<src[i]; 80 } 81 cout<<endl; 82 } 83 84 void initArray(char a[],int n) 85 { 86 int i; 87 for (i = 0; i < n; i++) 88 { 89 a[i] = ‘\0‘; 90 } 91 } 92 93 int calculate(int a,int b,char op) 94 { 95 switch (op) 96 { 97 case ‘+‘: 98 return a+b; 99 break;100 case ‘-‘:101 return a-b;102 break;103 case ‘*‘:104 return a*b;105 break;106 case ‘/‘:107 if (b != 0)108 {109 return a/b;110 }111 else112 {113 return 0;114 }115 default:116 perror("error!\n");117 }118 }119 120 int calculatePostfix(const vector<char> &src)121 {122 stack<int> stk;123 char str[10];124 int i,n,temp,k;125 int opd1,opd2;126 int result;127 128 n = src.size();129 130 for (i = 0; i < n; i++)131 {132 switch(src[i])133 {134 case ‘#‘:135 break;136 case ‘+‘:137 case ‘-‘:138 case ‘*‘:139 case ‘/‘:140 opd2 = stk.top();141 stk.pop();142 opd1 = stk.top();143 stk.pop();144 result = calculate(opd1,opd2,src[i]);145 stk.push(result);146 break;147 default:148 k = 0;149 while ((isdigit(src[i])) && (i < n))150 {151 str[k++] = src[i++];152 }153 temp = atoi(str);154 stk.push(temp);155 initArray(str,10);156 i--;157 }158 }159 return result;160 }161 162 int main()163 {164 ifstream in("data.txt");165 string src;166 int result;167 vector<char> postfix;168 getline(in,src);169 170 setPriority();171 InfixToPostfix(src,postfix);172 displayExp(postfix);173 result = calculatePostfix(postfix);174 cout<<src<<" = "<<result;175 cout<<endl;176 return 0;177 }
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。