版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/DEEPWAVE98/article/details/84717385
本文用C++实现了求一个简单函数的定积分
(目前仅支持一元四则混合运算)
说明:
求定积分部分采用的是辛普森积分法
表达式匹配部分采用的是表达式二叉树计算
code:
/*
Date:2018.12.2
Author:DeepWave
*/
#include<bits/stdc++.h>
using namespace std;
#define Var map<string,double>
const double eps = 1e-12; //精度设置
Var vars; //变量预定义
string str; //表达式
string variable; //变量名
double a, b; //积分上下限
class Expression;
class Constant;
class UnkownNumber;
class Operation;
class Integral;
Expression *expressionTree(string s, int start, int len);
void Initialization();
class Expression
{
public:
virtual double Evaluate(Var v)
{
return 0;
}
};
Expression *EXP; //表达式树
/*
常数类
*/
class Constant : public Expression
{
public:
double value;
Constant(double value)
{
this->value = value;
}
double Evaluate(Var vars)
{
return value;
}
};
/*
操作符类
由传入的左右子表达式计算
*/
class Operation: public Expression
{
public:
char op;
Expression *Left, *Right;
Operation(Expression *Left, Expression *Right, char op)
{
this->Left = Left;
this->Right = Right;
this->op = op;
}
double Evaluate(Var v)
{
double x = Left->Evaluate(v);
double y = Right->Evaluate(v);
switch(op)
{
case'+':
return x + y;
case'-':
return x - y;
case'*':
return x * y;
case'/':
return x / y;
}
return 0;
}
};
/*
未知数类
将表达式中的未知数进行转换
*/
class UnkownNumber: public Expression
{
public:
string name;
UnkownNumber(string name)
{
this->name = name;
}
double Evaluate(Var v)
{
return vars[name];
}
};
/*
由字符串转为表达式树
*/
Expression *expressionTree(string s, int start, int len)
{
bool hasAlpha = false, hasOperator = false;
int bracket = 0, PS = -1, MD = -1;
while(start <= len && s[start] == '(' && s[len] == ')')
start++, len--;
if(start > len)
return new Constant(0);
for(int i = start; i <= len; i++)
{
if(s[i] != '.' && !isdigit(s[i]))
{
if(isalpha(s[i]))
hasAlpha = true;
else
{
hasOperator = true;
switch(s[i])
{
case '+':
case '-':
if(!bracket) PS = i;
break;
case '*':
case '/':
if(!bracket) MD = i;
break;
case '(':
bracket++;
break;
case ')':
bracket--;
break;
}
}
}
}
if(hasAlpha == false && hasOperator == false)
return new Constant(stod(s.substr(start, len - start + 1)));
else if(hasOperator == false)
return new UnkownNumber(s.substr(start, len - start + 1));
else
{
int mid = PS == -1 ? MD : PS;
return new Operation(expressionTree(s, start, mid - 1), expressionTree(s, mid + 1, len), s[mid]);
}
return 0;
}
/*
积分类
*/
class Integral
{
public:
double a, b;
Integral(double a, double b)
{
this->a = a;
this->b = b;
}
double Function(double x)
{
vars[variable]=x;
return EXP->Evaluate(vars);
}
double simpson(double a, double b)
{
double c = a + (b - a) / 2;
return (Function(a) + 4 * Function(c) + Function(b)) * (b - a) / 6.0;
}
double calculate(double a, double b, double Eps)
{
double c = a + (b - a) / 2;
double mid = simpson(a, b);
double Left = simpson(a, c);
double Right = simpson(c, b);
if(fabs(Left + Right - mid) <= 15.0 * eps)
return Left + Right + (Left + Right - mid) / 15.0;
return calculate(a, c, Eps / 2.0) + calculate(c, b, Eps / 2.0);
}
double Evaluate(double Eps)
{
double up, down;
down = this->a;
up = this->b;
return calculate(down, up, Eps);
}
};
void Initialization() //可预设常量值
{
vars["e"] = 2.7182818284;
vars["pi"] = acos(-1);
}
int main()
{
Initialization();
cout << "Please enter an expression that requires integration.(linear equation with one unknown)" << endl;
cin >> str;
EXP = expressionTree(str, 0, str.length() - 1);
cout << "Please enter the upper and lower limit of the integral." << endl;
cin >> a >> b;
cout << "Please input variable name." << endl;
cin >> variable;
Integral I (a, b);
printf("%.5f\n", I.Evaluate(eps));
return 0;
}