当我们输入一个数学表达式,是中缀表达式,我们首先转换为后缀表达式(逆波兰表达式),然后再进行求值。

代码思路:

(1)首先对输入的中缀表达式合法性进行判断,bool isStringLegal(const char* str); 函数实现。

(2)然后把中缀表达式转换为后缀表达式。

(3)根据后缀表达式求出结果,double getTheResult(vector<string> &vec);函数实现。

注意:表达式的运算符可以输入 加、减、乘、除、括号,输入的数据为整形数据,计算结果为double型数据。

  1 #include <iostream>
2 #include <math.h>
3 #include <map>
4 #include <vector>
5 #include <string.h>
6 #include <memory>
7 #include <string>
8 #include <stdio.h>
9 #include <stack>
10 #include <stdlib.h>
11
12 using namespace std;
13
14 #define MAX_STRING_LENGTH 100
15
16 /* 解析当前的整形数据,并把整形数据转换为string型 */
17 string analyData(const char* str, int &i);
18
19 /* 根据逆波兰表达式求表达式的值 */
20 double getTheResult(vector<string> &vec);
21
22 /* 判断该字符是否是 + - * / ( ) */
23 bool isCalChar(const char ch);
24
25 /* 判断输入的中缀表达式是否合法 */
26 bool isStringLegal(const char* str);
27
28
29
30 /* 解析当前的整形数据,并把整形数据转换为string型 */
31 string analyData(const char* str, int &i)
32 {
33 int temp = i++;
34 while(str[i] >= '0' && str[i] <= '9' && str[i] != '\0')
35 {
36 i++;
37 }
38
39 string s(str+temp,str+i);
40
41 return s;
42 }
43
44 /* 根据逆波兰表达式求表达式的值 */
45 double getTheResult(vector<string> &vec)
46 {
47 vector<string>::iterator it;
48 stack<double> sta;
49
50 string strTemp;
51 double d = 0, d1 = 0, d2 = 0;
52
53 for(it = vec.begin(); it != vec.end(); it++)
54 {
55 strTemp = (*it);
56
57 if(strTemp == "+")
58 {
59 d1 = sta.top();
60 sta.pop();
61
62 d2 = sta.top();
63 sta.pop();
64
65 d = d1 + d2;
66 sta.push(d);
67 }
68 else if(strTemp == "-")
69 {
70 d1 = sta.top();
71 sta.pop();
72
73 d2 = sta.top();
74 sta.pop();
75
76 d = d2 - d1;
77 sta.push(d);
78 }
79 else if(strTemp == "*")
80 {
81 d1 = sta.top();
82 sta.pop();
83
84 d2 = sta.top();
85 sta.pop();
86
87 d = d2 * d1;
88 sta.push(d);
89 }
90 else if(strTemp == "/")
91 {
92 d1 = sta.top();
93 sta.pop();
94
95 d2 = sta.top();
96 sta.pop();
97
98 d = d2 / d1;
99 sta.push(d);
100 }
101 else
102 {
103 const char *p = strTemp.c_str();
104 d = atoi(p);
105 sta.push(d);
106 }
107 }
108 return sta.top();
109 }
110
111 /* 判断该字符是否是 + - * / ( ) */
112 bool isCalChar(const char ch)
113 {
114 if(ch == '+' || ch == '-' || ch == '*' || ch == '/' || ch == '(' || ch == ')')
115 {
116 return true;
117 }
118
119 return false;
120 }
121 /* 判断输入的中缀表达式是否合法 */
122 bool isStringLegal(const char* str)
123 {
124 /* 判断是否是空串 */
125 if(NULL == str)
126 {
127 return false;
128 }
129
130 int len = strlen(str);
131 int i = 0;
132 int flag = 0;
133
134 /* 字符串的开头和末尾是否是数字 */
135 if(str[0] > '9' || str[0] < '0' || str[len-1] > '9' || str[len-1] < '0')
136 {
137 return false;
138 }
139
140
141 for(i = 0; str[i] != '\0'; i++)
142 {
143 /* 是否有除了加减乘除括号之外的字符 */
144 if(isCalChar(str[i]) == false)
145 {
146 return false;
147 }
148
149 /* 判断是否有两个连续的符号 */
150 if(i < len-1 && isCalChar(str[i]) == true)
151 {
152 if(isCalChar(str[i+1]) == true)
153 {
154 return false;
155 }
156
157 }
158
159 /* 判断括号是否成对 */
160 if(str[i] == '(')
161 {
162 flag++;
163 }
164 else if(str[i] == ')')
165 {
166 flag--;
167 }
168
169 /* 判断是否出现 )( 这样的情况 */
170 if(flag < 0)
171 {
172 return false;
173 }
174 }
175
176 /* 判断括号是否匹配 */
177 if(flag != 0)
178 {
179 return false;
180 }
181
182 return true;
183 }
184
185 int main(void)
186 {
187 char str[MAX_STRING_LENGTH] = {0};
188 int i = 0;
189 string data;
190
191 /* 存放运算符表达式的栈 */
192 stack<char> oper_char;
193
194 /* 存放后缀表达式 */
195 vector<string> post_str;
196
197 /* 输入中缀的表达式 */
198 gets(str);
199
200 /* 判断输入的中缀表达式是否合法 */
201 if(isStringLegal(str) != true)
202 {
203 cout << "This expression is not legal." << endl;
204 }
205 else
206 {
207 /* 将中缀表达式转换为后缀表达式 */
208 for(i = 0; str[i] != '\0'; i++)
209 {
210 /* 如果该字符为数字,解析该数字,并压入栈 */
211 if(str[i] >= '0' && str[i] <= '9')
212 {
213 data = analyData(str,i);
214 post_str.push_back(data);
215 i--;
216 }
217 else if(str[i] == '(')
218 {
219 oper_char.push(str[i]);
220 }
221 else if(str[i] == ')')
222 {
223 char chtemp[2] = {0};
224
225 chtemp[0] = oper_char.top();
226
227 while(chtemp[0] != '(')
228 {
229 string strtemp(chtemp);
230 post_str.push_back(strtemp);
231 oper_char.pop();
232
233 chtemp[0] = oper_char.top();
234 }
235 oper_char.pop();
236 }
237 else if(str[i] == '+' || str[i] == '-')
238 {
239 char chtemp[2] = {0};
240
241 /* 全部出栈,但是碰到 '('就要停止出栈 */
242 while(oper_char.size() != 0)
243 {
244 chtemp[0] = oper_char.top();
245 if(chtemp[0] == '(')
246 {
247 break;
248 }
249
250 oper_char.pop();
251
252 string strtemp(chtemp);
253 post_str.push_back(strtemp);
254 }
255
256 /*将当前的表达式符号入栈*/
257 oper_char.push(str[i]);
258 }
259 else if(str[i] == '*' || str[i] == '/')
260 {
261 char chtemp[2] = {0};
262 while(oper_char.size() != 0)
263 {
264 chtemp[0] = oper_char.top();
265 if(chtemp[0] == '(' || chtemp[0] == '+' || chtemp[0] == '-')
266 {
267 break;
268 }
269 else
270 {
271 oper_char.pop();
272
273 string strtemp(chtemp);
274 post_str.push_back(strtemp);
275 }
276 }
277
278 /*将当前的表达式符号入栈*/
279 oper_char.push(str[i]);
280 }
281 }
282
283 /* 存放表达式的栈可能还有数据 */
284 while(!oper_char.empty())
285 {
286 char chtemp[2] = {0};
287 chtemp[0] = oper_char.top();
288 oper_char.pop();
289
290 string strtemp(chtemp);
291 post_str.push_back(strtemp);
292 }
293
294 /* 把逆波兰表达式求值 */
295 cout << getTheResult(post_str) << endl;
296 }
297
298 return 0;
299 }

逆波兰(加、减、乘、除、括号)表达式原理及C++代码实现的更多相关文章

  1. SQLServer学习笔记<>日期和时间数据的处理(cast转化格式、日期截取、日期的加减)和 case表达式

    日期和时间数据的处理. (1)字符串日期 ‘20080301’,这一串为字符串日期,但必须保证为四位的年份,两位的月份,两位的日期.例如,查询订单表日期大于‘20080301’.可以这样写: 1 se ...

  2. 逆波兰(非与或)表达式原理及C++代码实现

    p.p1 { margin: 0; font: 11px Menlo; color: rgba(209, 47, 27, 1); background-color: rgba(255, 255, 25 ...

  3. Java 实现《编译原理》中间代码生成 -逆波兰式生成与计算 - 程序解析

    Java 实现<编译原理>中间代码生成 -逆波兰式生成与计算 - 程序解析 编译原理学习笔记 (一)逆波兰式是什么? 逆波兰式(Reverse Polish notation,RPN,或逆 ...

  4. leetcode算法学习----逆波兰表达式求值(后缀表达式)

    下面题目是LeetCode算法:逆波兰表达式求值(java实现) 逆波兰表达式即后缀表达式. 题目:  有效的运算符包括 +, -, *, / .每个运算对象可以是整数,也可以是另一个逆波兰表达式.同 ...

  5. noi1696 逆波兰表达式

    1696:逆波兰表达式 http://noi.openjudge.cn/ch0303/1696/ 总时间限制:  1000ms 内存限制:  65536kB 描述 逆波兰表达式是一种把运算符前置的算术 ...

  6. c++实现将表达式转换为逆波兰表达式

    https://github.com/Lanying0/lintcode 所属: 数据结构->线性结构->栈 问题: 给定一个表达式字符串数组,返回该表达式的逆波兰表达式(即去掉括号). ...

  7. java 逆波兰表达式

    最近想把这破机 装成WIN7 想想还是算了 ...  反正用的机会也不多. 不过 发现了一些 想念的东西 从前的作业. 从前的记忆. package org.lmz; import java.util ...

  8. nyoj35——逆波兰表达式

    逆波兰表达式又称作后缀表达式,在四则混合运算的程序设计中用到. 例如: 1+2写成后缀表达式就是12+ 4+5*(3-2)的后缀表达式就是4532-*+ 后缀表达式在四则运算中带来了意想不到的方便,在 ...

  9. [LeetCode] 150. Evaluate Reverse Polish Notation 计算逆波兰表达式

    Evaluate the value of an arithmetic expression in Reverse Polish Notation. Valid operators are +, -, ...

随机推荐

  1. illumina SNP 芯片转基因型矩阵

    一.芯片数据 此次拿到的illumina芯片数据并不是原始的数据,已经经过GenomeStudio软件处理成了finalreport文件,格式如下: 之前没处理过芯片数据,对于这种编码模式(Forwa ...

  2. 利用vcftools比较两个vcf文件

    因为最近有一项工作是比较填充准确性的,中间有用到vcftools比较两个vcf文件. 使用命令也很简单: 1 vcftools --vcf file1.snp.vcf --diff file2.snp ...

  3. windows下typora图片自动上传到图床(附带腾讯云教程)

    目录 1. 背景 2. 在Typora中使用 3. 安装 3.1 安装教程环境说明 3.2 安装步骤 3.3 配置图床 3.3.1 插件配置 3.3.2 腾讯云参数获取 3.3.2.1 新建子用户,获 ...

  4. WINDOWS中使用svn

    官网:https://tortoisesvn.net/index.zh.html  (SVN安装包) 然后下载对应的64位安装包(语言包) 安装完后运行 可以存到D盘,新建一个文件夹存放 右键桌面会多 ...

  5. 网站性能调优实战-学相伴KuangStudy

    面对并发我们是如何优化KuangStudy网站性能的? 每个项目都会随着用户和数据的增长调整架构,来面对未来的问题,我们也不例外,在1月5号我们平台正式公测后,引起了很多观众的热烈反响,仅仅4天,注册 ...

  6. A Child's History of England.13

    Then came the boy-king, Edgar, called the Peaceful, fifteen years old. Dunstan, being still the real ...

  7. 利用python爬取城市公交站点

    利用python爬取城市公交站点 页面分析 https://guiyang.8684.cn/line1 爬虫 我们利用requests请求,利用BeautifulSoup来解析,获取我们的站点数据.得 ...

  8. 我在项目中是这样配置Vue的

    启用压缩,让页面加载更快 在我们开发的时候,为了方便调试,我们需要使用源码进行调试,但在生产环境,我们追求的更多的是加载更快,体验更好,这时候我们会将代码中的空格注释去掉,对代码进行混淆压缩,只为了让 ...

  9. 单链表的模板类(C++)

    /*header.h*/#pragma once #include<iostream> using namespace std; template<class T> struc ...

  10. Mybatis 批量插入

    一.首先对于批量数据的插入有两种解决方案(下面内容只讨论和Mysql交互的情况) 1)for循环调用Dao中的单条插入方法 2)传一个List<Object>参数,使用Mybatis的批量 ...