求定積分 c++實現
阿新 • • 發佈:2018-12-03
本文用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; }