表达式中可以有四则运算符、括号、整数/实数值、已经赋值的符号名和预定义的符号常量( pi 和 e ),也可以只有单个的整数/实数值。 发现输入内容与文法不符或将导致非法计算时,则从标准输出设备输出出错提示,并计算出错次数。写出此c++程序并给出注释

时间: 2024-02-29 12:52:27 浏览: 23
以下是一个实现上述功能的C++程序,其中使用了map来存储符号名和符号常量: ```cpp #include <iostream> #include <string> #include <stack> #include <map> #include <cmath> using namespace std; // 定义常量 pi 和 e const double PI = 3.141592653589793; const double E = 2.718281828459045; // 获取符号的优先级 int priority(char op) { if (op == '+' || op == '-') return 1; if (op == '*' || op == '/') return 2; return 0; } // 计算两个数的结果 double calculate(double a, double b, char op) { if (op == '+') return a + b; if (op == '-') return a - b; if (op == '*') return a * b; if (op == '/') return a / b; return 0; } // 判断一个字符串是否为数字 bool is_number(const string& s) { for (int i = 0; i < s.length(); i++) { if (!isdigit(s[i]) && s[i] != '.') return false; } return true; } // 处理符号名或符号常量 double process_symbol(const string& symbol, const map<string, double>& symbols) { if (symbols.find(symbol) != symbols.end()) { return symbols.at(symbol); } if (symbol == "pi") { return PI; } if (symbol == "e") { return E; } return 0; } // 计算表达式的值 double evaluate(const string& expression, map<string, double>& symbols) { stack<double> operands; stack<char> operators; for (int i = 0; i < expression.length(); i++) { if (isdigit(expression[i]) || expression[i] == '.') { // 处理数字 double operand = 0; while (i < expression.length() && (isdigit(expression[i]) || expression[i] == '.')) { operand = operand * 10 + (expression[i] - '0'); i++; } i--; operands.push(operand); } else if (isalpha(expression[i])) { // 处理符号名 string symbol; while (i < expression.length() && (isalnum(expression[i]) || expression[i] == '_')) { symbol += expression[i]; i++; } i--; double value = process_symbol(symbol, symbols); if (value == 0) { cout << "Error: undefined symbol \"" << symbol << "\"" << endl; return -1; } operands.push(value); } else if (expression[i] == '(') { // 处理左括号 operators.push(expression[i]); } else if (expression[i] == ')') { // 处理右括号 while (operators.top() != '(') { double b = operands.top(); operands.pop(); double a = operands.top(); operands.pop(); char op = operators.top(); operators.pop(); operands.push(calculate(a, b, op)); } operators.pop(); // 弹出左括号 } else if (expression[i] == '+' || expression[i] == '-' || expression[i] == '*' || expression[i] == '/') { // 处理运算符 while (!operators.empty() && priority(operators.top()) >= priority(expression[i])) { double b = operands.top(); operands.pop(); double a = operands.top(); operands.pop(); char op = operators.top(); operators.pop(); operands.push(calculate(a, b, op)); } operators.push(expression[i]); } else { // 非法字符 cout << "Error: invalid character '" << expression[i] << "'" << endl; return -1; } } while (!operators.empty()) { // 处理剩余的运算符 double b = operands.top(); operands.pop(); double a = operands.top(); operands.pop(); char op = operators.top(); operators.pop(); operands.push(calculate(a, b, op)); } return operands.top(); } int main() { map<string, double> symbols; int error_count = 0; while (true) { string input; getline(cin, input); if (input == "quit") { break; } double result = evaluate(input, symbols); if (result == -1) { error_count++; } else { cout << result << endl; } } cout << "Number of errors: " << error_count << endl; return 0; } ``` 在这个实现中,我们使用了map来存储符号名和符号常量的值。在计算表达式时,我们首先扫描表达式并处理以下情况: 1. 如果当前字符是数字或小数点,则将其作为操作数压入操作数栈中。 2. 如果当前字符是字母,则将其作为符号名处理,并在符号表中查找其对应的值。如果找到了对应的值,则将其作为操作数压入操作数栈中;否则输出错误信息。 3. 如果当前字符是左括号,则将其压入操作符栈中。 4. 如果当前字符是右括号,则从操作符栈中弹出操作符和操作数栈中的两个操作数,计算它们的值,并将结果压入操作数栈中,直到遇到左括号。 5. 如果当前字符是操作符,则从操作符栈中弹出操作符和操作数栈中的两个操作数,计算它们的值,并将结果压入操作数栈中,直到操作符栈为空或者栈顶操作符的优先级小于当前操作符的优先级。然后将当前操作符压入操作符栈中。 6. 如果当前字符是其他非法字符,则输出错误信息。 最后,当我们处理完整个表达式后,我们从操作符栈中弹出操作符和操作数栈中的两个操作数,计算它们的值,并将结果压入操作数栈中,直到操作数栈中只剩下一个元素为止。这个元素就是表达式的值。

相关推荐

最新推荐

recommend-type

Mysql语法、特殊符号及正则表达式的使用详解

Mysql常用显示命令 1、显示当前数据库服务器中的数据库列表: mysql&gt; SHOW DATABASES; ... 2、进入数据库: mysql&gt; USE 库名; 2、显示数据库中的数据表: ...mysql&gt; CREATE TABLE 表名 (字段名 VARCHAR(20), 字段名
recommend-type

编译原理——无符号数的算术四则运算语义处理程序实现

对实验一进行扩展,对识别的无符号数进行计值,并将输出形式改为(类别码,值)的二元式形式。 对实验二进行扩展,计算并输出算术表达式的值。...如果不是无符号数的算术四则运算,输出“非法四则运算表达式”。
recommend-type

使用JS正则表达式 替换括号,尖括号等

下面小编就为大家带来一篇使用JS正则表达式 替换括号,尖括号等。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
recommend-type

jsp页面中表达式语言中的$符号不起作用的解决方法

今天myeclipse里部署了之前做的一个测试项目,发现jsp里的$符号tomcat启动后页面上显示出来了,百度搜了下别人也有类似的问题出现过。经提醒原来是web.xml配置的version设置的是2.5而我tomcat5启动的。是tomcat的...
recommend-type

正则表达式全局匹配模式(g修饰符)

g修饰符用语规定正则表达式执行全局匹配,也就是在找到第一个匹配之后仍然会继续查找
recommend-type

zigbee-cluster-library-specification

最新的zigbee-cluster-library-specification说明文档。
recommend-type

管理建模和仿真的文件

管理Boualem Benatallah引用此版本:布阿利姆·贝纳塔拉。管理建模和仿真。约瑟夫-傅立叶大学-格勒诺布尔第一大学,1996年。法语。NNT:电话:00345357HAL ID:电话:00345357https://theses.hal.science/tel-003453572008年12月9日提交HAL是一个多学科的开放存取档案馆,用于存放和传播科学研究论文,无论它们是否被公开。论文可以来自法国或国外的教学和研究机构,也可以来自公共或私人研究中心。L’archive ouverte pluridisciplinaire
recommend-type

MATLAB柱状图在信号处理中的应用:可视化信号特征和频谱分析

![matlab画柱状图](https://img-blog.csdnimg.cn/3f32348f1c9c4481a6f5931993732f97.png) # 1. MATLAB柱状图概述** MATLAB柱状图是一种图形化工具,用于可视化数据中不同类别或组的分布情况。它通过绘制垂直条形来表示每个类别或组中的数据值。柱状图在信号处理中广泛用于可视化信号特征和进行频谱分析。 柱状图的优点在于其简单易懂,能够直观地展示数据分布。在信号处理中,柱状图可以帮助工程师识别信号中的模式、趋势和异常情况,从而为信号分析和处理提供有价值的见解。 # 2. 柱状图在信号处理中的应用 柱状图在信号处理
recommend-type

HSV转为RGB的计算公式

HSV (Hue, Saturation, Value) 和 RGB (Red, Green, Blue) 是两种表示颜色的方式。下面是将 HSV 转换为 RGB 的计算公式: 1. 将 HSV 中的 S 和 V 值除以 100,得到范围在 0~1 之间的值。 2. 计算色相 H 在 RGB 中的值。如果 H 的范围在 0~60 或者 300~360 之间,则 R = V,G = (H/60)×V,B = 0。如果 H 的范围在 60~120 之间,则 R = ((120-H)/60)×V,G = V,B = 0。如果 H 的范围在 120~180 之间,则 R = 0,G = V,B =
recommend-type

JSBSim Reference Manual

JSBSim参考手册,其中包含JSBSim简介,JSBSim配置文件xml的编写语法,编程手册以及一些应用实例等。其中有部分内容还没有写完,估计有生之年很难看到完整版了,但是内容还是很有参考价值的。