Skip to content

Commit 69fef2d

Browse files
author
冷漠
committed
奇怪的运算符重载&对数函数求导&建树bug修复
1 parent 0e217e4 commit 69fef2d

File tree

6 files changed

+115
-57
lines changed

6 files changed

+115
-57
lines changed

SCMath.pro.user

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<!DOCTYPE QtCreatorProject>
3-
<!-- Written by QtCreator 4.5.0, 2019-02-17T15:06:51. -->
3+
<!-- Written by QtCreator 4.5.0, 2019-02-18T02:07:00. -->
44
<qtcreator>
55
<data>
66
<variable>EnvironmentId</variable>

ast.cpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ BasicNode* ast::__ToAST(string &s)
8080
j++;//整数部分
8181
if (s[j] == '.' && j + 1 < n && isNum(s[j + 1])) {
8282
j++;//小数部分
83-
while (j < n && isNum(s[j + 1]))
83+
while (j < n && isNum(s[j]))
8484
{
8585
j++;
8686
}
@@ -100,10 +100,17 @@ BasicNode* ast::__ToAST(string &s)
100100
//此时s[j] == '('
101101
while(s[j] != ')' && s[j] != LowestPriority)
102102
{
103+
int countleftParenthesis = 1;
103104
i = j;
104105
j++;
105-
while(j < n && s[j] != ',' && s[j] != ')' && s[j] != LowestPriority)
106+
while(j < n && s[j] != ',' && s[j] != LowestPriority && countleftParenthesis != 0)
107+
{
106108
j++;
109+
if(s[j] == '(')
110+
countleftParenthesis++;
111+
if(s[j] == ')')
112+
countleftParenthesis--;
113+
}
107114
node->addNode(ToAST(s.substr(i + 1, j - i - 1)));
108115
}
109116
stackAST.push(node);

main.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,5 +71,14 @@ int main()
7171
Simplificate(ansAfterDerivation);
7272
output::outputAST(ansAfterDerivation);
7373
cout << endl << endl;
74+
75+
TestDerivation = "log(2.7182818,cos(x))";
76+
ansTestDerivation = ast::ToAST(TestDerivation);
77+
output::outputAST(ansTestDerivation);
78+
cout << endl;
79+
ansAfterDerivation = Derivation(ansTestDerivation, "x");
80+
Simplificate(ansAfterDerivation);
81+
output::outputAST(ansAfterDerivation);
82+
cout << endl << endl;
7483
return 0;
7584
}

nodetype.cpp

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#include "nodetype.h"
2+
#include "ast.h"
23

34
bool copyHelp::isLiteral(int type) //warn:是否为字面量,添加新的字面量要进行修改
45
{
@@ -27,6 +28,47 @@ BasicNode::~BasicNode()
2728
}
2829

2930

31+
BasicNode* BasicNode::operator +(BasicNode& rhs)
32+
{
33+
BasicNode* retn = new FunNode(record::globalScope.functionList["+"]);
34+
retn->addNode(copyHelp::copyNode(this));
35+
retn->addNode(copyHelp::copyNode(&rhs));
36+
return retn;
37+
}
38+
39+
BasicNode* BasicNode::operator -(BasicNode& rhs)
40+
{
41+
BasicNode* retn = new FunNode(record::globalScope.functionList["-"]);
42+
retn->addNode(copyHelp::copyNode(this));
43+
retn->addNode(copyHelp::copyNode(&rhs));
44+
return retn;
45+
}
46+
47+
BasicNode* BasicNode::operator *(BasicNode& rhs)
48+
{
49+
BasicNode* retn = new FunNode(record::globalScope.functionList["*"]);
50+
retn->addNode(copyHelp::copyNode(this));
51+
retn->addNode(copyHelp::copyNode(&rhs));
52+
return retn;
53+
}
54+
55+
BasicNode* BasicNode::operator /(BasicNode& rhs)
56+
{
57+
BasicNode* retn = new FunNode(record::globalScope.functionList["/"]);
58+
retn->addNode(copyHelp::copyNode(this));
59+
retn->addNode(copyHelp::copyNode(&rhs));
60+
return retn;
61+
}
62+
63+
BasicNode* BasicNode::operator ^(BasicNode& rhs)
64+
{
65+
BasicNode* retn = new FunNode(record::globalScope.functionList["^"]);
66+
retn->addNode(copyHelp::copyNode(this));
67+
retn->addNode(copyHelp::copyNode(&rhs));
68+
return retn;
69+
}
70+
71+
3072
VarNode::VarNode(int valtype)
3173
{
3274
this->valtype=valtype;

nodetype.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include <functional>
55
#include "marco.h"
66
#include "excep.h"
7+
#define D(x) *(x)
78
using namespace std;
89

910
class BasicNode
@@ -22,6 +23,13 @@ class BasicNode
2223
void setRet() {this->retFlag=true;} //不可eval节点设置ret无效
2324
bool isRet() const {return this->retFlag;}
2425
vector<BasicNode*> sonNode;
26+
27+
BasicNode* operator +(BasicNode&);
28+
BasicNode* operator -(BasicNode&);
29+
BasicNode* operator *(BasicNode&);
30+
BasicNode* operator /(BasicNode&);
31+
BasicNode* operator ^(BasicNode&);
32+
2533
};
2634
typedef function<bool(vector<BasicNode*>&sonNode)>canBE; //检测函数基础求值参数表是否合法
2735
typedef function<BasicNode*(vector<BasicNode*>&sonNode)>BE; //进行基础求值

scmath.cpp

Lines changed: 46 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -151,80 +151,72 @@ BasicNode* Derivation(BasicNode* now, const string &value){
151151
if(op == "/")//除法:f / g == (f' * g - g' * f) / g ^ 2
152152
{
153153
BasicNode *f = temp->sonNode[0], *g = temp->sonNode[1];
154-
FunNode* retn = new FunNode(temp->getEntity());
155-
FunNode* retnson = new FunNode(record::globalScope.functionList["-"]);
156-
FunNode* retnsonson = new FunNode(record::globalScope.functionList["*"]);//忽略这个粗糙的变量名称
157-
retnsonson->addNode(Derivation(f, value));
158-
retnsonson->addNode(copyHelp::copyNode(g));
159-
retnson->addNode(retnsonson);//(f' * g - 部分
160-
retnsonson = new FunNode(record::globalScope.functionList["*"]);
161-
retnsonson->addNode(Derivation(g, value));
162-
retnsonson->addNode(copyHelp::copyNode(f));
163-
retnson->addNode(retnsonson);//g' * f) 部分
164-
retn->addNode(retnson);//返回的树的分子部分
165-
retnson = new FunNode(record::globalScope.functionList["^"]);
166-
retnson->addNode(copyHelp::copyNode(g));
167-
retnson->addNode(new NumNode(2));
168-
retn->addNode(retnson);//分母部分
154+
BasicNode *df = Derivation(f, value), *dg = Derivation(g, value);
155+
BasicNode* num2 = new NumNode(2);
156+
BasicNode* retn = D(D(D(df) * D(g)) - D(D(dg) * D(f))) / D(D(g) ^ D(num2));//^的优先级比较低,要加括号
157+
delete df;
158+
delete dg;
169159
return retn;
170160
}
171161

172162
if(op == "^")//幂:(f^g)' == (f ^ g) * (g' * ln f + g * f' / f)
173163
{
174164
BasicNode *f = temp->sonNode[0], *g = temp->sonNode[1];
175-
FunNode* retn = new FunNode(record::globalScope.functionList["*"]);
176-
FunNode* retnson = new FunNode(temp->getEntity());
177-
FunNode* retnsonson, *retnsonsonson;
178-
retnson->addNode(copyHelp::copyNode(f));
179-
retnson->addNode(copyHelp::copyNode(g));
180-
retn->addNode(retnson);//(f^g) * 部分
181-
retnson = new FunNode(record::globalScope.functionList["+"]);
182-
retnsonson = new FunNode(record::globalScope.functionList["*"]);
183-
retnsonson->addNode(Derivation(g, value));
184-
retnsonsonson = new FunNode(record::globalScope.functionList["log"]);
185-
retnsonsonson->addNode(new NumNode(std::exp(1)));
186-
retnsonsonson->addNode(copyHelp::copyNode(f));
187-
retnsonson->addNode(retnsonsonson);
188-
retnson->addNode(retnsonson);//(g' * ln f + 部分
189-
retnsonson = new FunNode(record::globalScope.functionList["*"]);
190-
retnsonsonson = new FunNode(record::globalScope.functionList["/"]);
191-
retnsonsonson->addNode(Derivation(f, value));
192-
retnsonsonson->addNode(copyHelp::copyNode(f));
193-
retnsonson->addNode(copyHelp::copyNode(g));
194-
retnsonson->addNode(retnsonsonson);
195-
retnson->addNode(retnsonson);//g * f' / f) 部分
196-
retn->addNode(retnson);
165+
BasicNode *df = Derivation(f, value), *dg = Derivation(g, value);
166+
BasicNode* lnf = new FunNode(record::globalScope.functionList["log"]);
167+
lnf->addNode(new NumNode(std::exp(1)));
168+
lnf->addNode(copyHelp::copyNode(f));
169+
BasicNode* retn = D(D(f) ^ D(g)) * D(D(D(dg) * D(lnf)) + D(D(D(g) * D(df)) / D(f)));
170+
delete df;
171+
delete dg;
172+
delete lnf;
197173
return retn;
198174
}
199175

200176
if(op == "sin")//正弦函数:(sin(f))' == f' * cos(f)
201177
{
202-
BasicNode* f = temp->sonNode[0];
203-
FunNode* retn = new FunNode(record::globalScope.functionList["*"]);
204-
FunNode* retnson = new FunNode(record::globalScope.functionList["cos"]);
205-
retnson->addNode(copyHelp::copyNode(f));//cos(f)部分
206-
retn->addNode(Derivation(f, value));
207-
retn->addNode(retnson);
178+
BasicNode *f = temp->sonNode[0];
179+
BasicNode *df = Derivation(f, value);
180+
BasicNode* cosf = new FunNode(record::globalScope.functionList["cos"]);
181+
cosf->addNode(copyHelp::copyNode(f));
182+
BasicNode* retn = D(df) * D(cosf);
183+
delete df;
184+
delete cosf;
208185
return retn;
209186
}
210187

211188
if(op == "cos")//余弦函数:(cos(f))' == -1 * f' * sin(f)
212189
{
213-
BasicNode* f = temp->sonNode[0];
214-
FunNode* retn = new FunNode(record::globalScope.functionList["*"]);
215-
FunNode* retnson = new FunNode(record::globalScope.functionList["*"]);
216-
FunNode* retnsonson = new FunNode(record::globalScope.functionList["sin"]);
217-
retnsonson->addNode(copyHelp::copyNode(f));//sin(f)部分
218-
retnson->addNode(Derivation(f, value));
219-
retnson->addNode(retnsonson);//f' * sin(f)部分
220-
retn->addNode(new NumNode(-1));
221-
retn->addNode(retnson);
190+
BasicNode *f = temp->sonNode[0];
191+
BasicNode *df = Derivation(f, value);
192+
BasicNode *numNeg1 = new NumNode(-1);
193+
BasicNode* sinf = new FunNode(record::globalScope.functionList["sin"]);
194+
sinf->addNode(copyHelp::copyNode(f));
195+
BasicNode* retn = D(numNeg1) * D(D(df) * D(sinf));
196+
delete df;
197+
delete numNeg1;
198+
delete sinf;
222199
return retn;
223200
}
224201

225-
if(op == "log")//对数函数:(log(f, g))' = g' / (g * log(e, f) - f' * log(e, g) / (f * log(e, f) ^ 2)
202+
if(op == "log")//对数函数:(log(f, g))' = g' / (g * log(e, f)) - f' * log(e, g) / (f * log(e, f) ^ 2)
226203
{
227-
//咕咕咕
204+
BasicNode *f = temp->sonNode[0], *g = temp->sonNode[1];
205+
BasicNode *df = Derivation(f, value), *dg = Derivation(g, value);
206+
BasicNode* lnf = new FunNode(record::globalScope.functionList["log"]);
207+
lnf->addNode(new NumNode(std::exp(1)));
208+
lnf->addNode(copyHelp::copyNode(f));
209+
BasicNode* lng = new FunNode(record::globalScope.functionList["log"]);
210+
lng->addNode(new NumNode(std::exp(1)));
211+
lng->addNode(copyHelp::copyNode(g));
212+
BasicNode* num2 = new NumNode(2);
213+
BasicNode* retn = D(D(dg) / D(D(g) * D(lnf))) - D(D(df) * D(D(lng) / D(D(f) * D(D(lnf) ^ D(num2)))));
214+
delete df;
215+
delete dg;
216+
delete lnf;
217+
delete lng;
218+
delete num2;
219+
return retn;
228220
}
229221
}
230222

0 commit comments

Comments
 (0)