用C++写一个数学表达式计算程序

由用户输入一个简单的四则运算表达式,求出其计算结果后显示。
允许在表达式中出现常用的数学函数,如绝对值、取整、三角函数、倒数、平方根、平方、立方等上。
这是我们C++的课设题目,要用C++语言写,求代码,最好代码有注释

编译原理的东西,对字符串的解析,还有定义好表达式的数据结构。
表达式是一种树状结构,表达式可以是最小的原子表达式(只有一个常量或者一个变量),也可以是由一个运算符和若干个子表达式组成的复合表达式,它的子表达式可以是元子表达式也可以是复合表达式。
我之前写过一个表达式类,可以运算,但是表达式的化简没有写好,效率低下。。。
下面是头文件,如果感兴趣可以向我索取剩下的代码:

#pragma once
#include "assert.h"
#include <vector>
using namespace std;

#define ConstantE 2.71828182845904523536 //自然对数e
#define ConstantPai 3.14159265358979323846 //圆周率π
#define InfinitePlus 1.0e308 //正无穷
#define InfiniteNegative -1.0e308 //负无穷
#define OperatorParam 5 //运算符允许的最大参数个数(也就是运算符的目数)
#define MaxExpressionTextParam 200 //表达式的“传文本参数”构造函数允许最大的字符串

enum ExpressionType //表达式类型
{
//每个枚举值所表示的含义必须一层层增大,即上一个枚举值是下一个枚举值的子集,但ExpressionType_unknown不是它上面枚举值的包含集
ExpressionType_plus=1, //正数(大于0的数)
ExpressionType_Unzero, //非零数
ExpressionType_num, //实数
ExpressionType_constant, //常数(包括复数)
//以上几个其实是常量
ExpressionType_unknown, //变量
//以上几个其实就是元子表达式,而下面的是表达式(包括元子表达式和复合表达式)
ExpressionType_expression, //表达式
};

enum ConstantType //常数类型
{
ConstantType_num=1, //实数数字
ConstantType_e, //自然数e
ConstantType_pai, //圆周率π
ConstantType_j, //虚数的j
};

struct Constant //常数
{
ConstantType eConstantType; //常数类型(可以表达实数部分c,虚数部分1*j,也可以表达1*e和1*π)
long double fValue; //数值(ejπ时无意义)
};

class Expression;
struct UnKnown //变量
{
//基本属性
unsigned int nID; //变量编号

//公式匹配
ExpressionType eExpressionType_Request; //匹配时该变量允许的类型(属性需求)
Expression* pExpression; //匹配上时,该变量指代的表达式(一个指针,不需要自己释放)

};

enum OperatorType //大部分运算符(暂时最大只出现双目运算)
{
OperatorType_Null=-1, //空运算符
OperatorType_add=0, //+(加)-----2目
OperatorType_sub, //-(减)-----2目
OperatorType_multi, //*(乘)-----2目
OperatorType_divide, ///(除)-----2目
OperatorType_abs, //||(绝对值)-----1目
OperatorType_inverse, //-(相反数)-----1目
OperatorType_factorial, //!(阶乘) -----1目
OperatorType_exponent, //^(指数)-----2目,参数1是底数
OperatorType_log, //log(对数,^逆运算)-----2目,参数1是底数
OperatorType_lg, //lg(10为底的对数)-----1目
OperatorType_ln, //ln(e为底的对数)-----1目
OperatorType_sin, //sin(正弦,对边比斜边)-----1目
OperatorType_cos, //cos(余弦,邻边比斜边)-----1目
OperatorType_tan, //tan(正切,对边比邻边)-----1目
OperatorType_cot, //cot(余切,邻边比对边)-----1目
OperatorType_sec, //sec(正割,斜边比邻边)-----1目
OperatorType_scs, //scs(余割,斜边比对边)-----1目
OperatorType_arcsin, //arcsin(sin逆运算)-----1目
OperatorType_arccos, //arccos(cos逆运算)-----1目
OperatorType_arctan, //arctan(tan逆运算)-----1目
OperatorType_arccot, //arccot(cot逆运算)-----1目
OperatorType_arcsec, //arcsec(sec逆运算)-----1目
OperatorType_arcscs, //arcscs(scs逆运算)-----1目
OperatorType_step, //ε单位阶跃函数-----1目,参数1是时间t(从0变到1,然后一直不变)
OperatorType_lash, //δ单位冲激函数-----1目,参数1是时间t(脉冲,瞬间变到无穷大,又瞬间回到0)
OperatorType_differ, //△(微分)-----2目(表达式,求微的未知数)
OperatorType_integral, //∫(积分)-----1目(表达式,求积的未知数)
};

struct OperatorProperty //运算符的属性(至少一目,最多允许十目),此结构只在(表达式和文本之间的转换)中使用
{
OperatorType eOperatorType; //运算符类型
unsigned int nCountParam; //运算符需要的参数个数(几目),0个参数表示无运算符号
char strRule[10]; //运算符文本书写规则,当元素是[0,9]时表示使用第几个参数,
//而当是其它时表示该运算符表达式中用到的特别字符。比如积分写成"∫0d1",写成数组方式就是('∫','0,','d','1'),
//注意文本书写方式中不允许出现小数点字符'.',以免增加分析的难度。
//另外,参数的数字编号也必须是从0开始按顺序递增,因为它指代了是第几个参数。
ExpressionType* peExpressionTypeArray_Request; //每个参数的表达式限制,默认都是ExpressionType_expression,
//但微积分中的最后一个参数要求是个未知数,数组大小是nCountParam
char** ppstrTextParam; //每个元素是运算符规则文本匹配时参数对应的实际文本
int nSite; //已匹配到运算符文本书写规则的哪个位置

};
class OperatorRule;
struct Expression
{
//表达式基本属性
string strText; //表达式的文本表示,下面是数据表示
//元子表达式(最精简的表达式,是常数或者变量,两者最多只有一个为非NULL)
Constant* pConstant; //常量
UnKnown* pUnknown; //变量
//复合表达式(子表达式的个数取决于运算符的目数)
OperatorType eOperatorType; //运算符类型(为了提高运算效率,使用多个变量替代数组的方式)
Expression* pExpressionSub1; //运算符使用到的子表达式1,复合表达式时必须非NULL(因为任何运算符至少需要一个参数)
Expression* pExpressionSub2; //运算符使用到的子表达式2,复合表达式时可能为NULL(单目运算符没第二个参数)
//Expression* pExpressionSub3;//超过双目时继续填写变量
};

struct OperatorRule //运算法则
{
//运算法则可分为“消元法则”(也可称为“优化法则”)和“普通法则”,另外还有“拉普拉式变换法则”。
//左表达式的树深度大于或者等于右表达式的。
//“消元法则”是指此法则可以有效地减少未知数的,也就是右表达式的未知数是左表达式的未知数的子集。
//“普通法则”则无法消去未知数的个数。
//“拉普拉式变换法则”的左边表达式是象函数,右边是原函数。
//“消元法则”和“拉普拉式变换法则”只允许从左边推导出右边,而“普通法则”则可以左右互相推导。
Expression* pExpression_Left; //法则的左边表达式
Expression* pExpression_Right; //法则的右边表达式
};
温馨提示:内容为网友见解,仅供参考
第1个回答  2012-06-23
建议你买一本C++之父写的《C++程序设计原理与实践》或者图书馆借一本,此书里面有非常详细四则运算表达式程序的讲解,并且我相信C++之父写的程序,一定比你从网上抄来的那些程序要更加地标准、更加严谨、正确。本回答被提问者和网友采纳
第2个回答  2012-06-23
自己完成吧
不是很难
通过看书和同学讨论都能做出来

求一个用C++编过计算器的,就是那种加减乘除三角函数可以写一排算的
break; case '+': case '-': while( top>=0 && stock[top]!='

用C++编写程序函数求表达式1-1\/2+1\/3-1\/4+1\/5-1\/6+1\/7-...+1\/n的值
int fun(int n){ double sum = 0.0;int k = 1;for(int i = 1; i <= n; i++){ sum += (1.0\/double(i))*k;k = k*(-1);} return sum;}

用C++编写一个计算器程序。用户输入两个运算数和四则运算符,输出计算结 ...
用C++编写的”输入两个运算数和四则运算符,输出计算结果”计算器程序代码具体如下:include<stdio.h> void main(){int a,b,d;char c;printf("请输入一种运算符:\\n");scanf("%c",&c);printf("请输入两个数:\\n");scanf("%d",&a);scanf("%d",&b);switch(c){ case '+':d=a+...

c++编程计算简单表达式的值
b, P;cout << "输入a b的值:";cin >> a >> b;P = 0.0204*a*pow(b, 1.775) + 0.0000548*a*a*b*b + 0.0000306 * pow(a, 1.5) * pow(b, 1.5);cout << "P = " << P << endl;return true;}

数学表达式写成C++算术表达式
1\/(1+1\/(1+1\/(x+y)));x*(x*(x*(a*x+b)+c)+d)+e;log(1+pow(fabs((a+b)\/(a-b)),10));sqrt(1+PI\/2*cos(48));1\/tan((1-x*x)\/(1+x*x)); \/\/由于C语言中没提供cot函数,所以就用tan的倒数表示了。log10(a*a+a*b+b*b);...

c++表达式计算
根据int a=3,b=4,c=2;(a+b)=7>4=c*2-->true;b!=5-->true;!(1\/2)=!(0)=1-->true;\/\/ 原因:1和2都是整数,因而1\/2仍然按整数进行计算得到0.5,实得0。于是(a+b)>c*2&&b!=5||!(1\/2)-->true。另外,即使改为(1.\/2)或者(1\/2.),因为在c语言中bool实质上是...

C++:编写一个程序能读入并计算一个只包含加减运算的表达式,每个输入的...
中缀转后缀表达式,然后对后缀表达式求值就可以了,这样不仅可以包含加减,还可以包含乘除括号、平方、开方等等

编写一个完整的c++程序,实现:求两个整数的最大值
\/\/ int sr[] = { a, b };int i = unsigned(c) >> (sizeof(int)* 8 - 1);\/\/推断c的最高位是0或者1,0则c是正数,1则c是负数。由此能够得出大小。\/\/unsigned类型的数字,往左移动的时候,无论怎样左边都补0。cout << sr[i] << endl;\/\/依据下标取出最大值。return 0;} ...

用c++语言 写 一个加减乘除的程序,分别用4个类写出来,求大神们的帮助啊...
STL里都自带了,他们分别是:plus<T> minus<T> multiplies<T> divides<T> modulus<T> negate<T> 如果你要解析混合运算的表达式, 请看看boost::spirite, 这个能够辅助解析

C语言编写一个求一元二次方程的实根的程序,该怎么写?
计算根:p=b*b-4*a*c; \/*给表达式赋值*\/ x1=(-b+sqrt(p))\/(2*a); \/*根1的值*\/ x2=(-b-sqrt(p))\/(2*a); \/*跟2的值*\/ 6.输出结果:printf("x1=%f,x2=%f\\n",x1,x2); \/*输出两个根的值*\/ 完整的源代码:include <stdio.h> include <math.h> void...

相似回答