我幾年前初學C++的時候,曾經花了很長時間實現了表達式的解析和運算,支持函數和變量,還能夠進行求導等操做,是我比較得意的成果,如今一翻看,卻以爲滿頭霧水,大概是當初沒有註釋的習慣,又習慣於把大段大段的代碼都塞在一個函數裏吧。 數組
此次決定從新進行一次實現,算是複習一下語法,也會使用一些最近才掌握的技巧。 函數
這個文件用來聲明所需的各類數據類型,我採用虛函數來實現運算,也就是說數值和變量也有求值運算。能夠看到我用了聯合來節省空間。 code
不打算使用後綴表達式數組來計算,而使用二叉樹,二叉樹的好處是,若是須要能夠方便的實現懶惰求值、求導。固然這個就不打算這麼作了,只是複習麼。 get
/* 0 1 2 3 4 5 6 7 8 9 左括號 逗號 右括號 數值 變量 函數1p 函數2p 算符1p 算符2p 賦值符 */ typedef double *Addrs; typedef double (*Fun1p)(double); typedef double (*Fun2p)(double,double); enum AtomType{Is_Empty,Is_Lquot,Is_Comma,Is_Rquot,Is_Value,Is_Param,Is_Fun1p,Is_Fun2p,Is_Opr1p,Is_Opr2p,Is_Setvr}; struct myFac { union { char opr[8]; double *adr; double vlu; Fun1p fc1; Fun2p fc2; }; virtual double get() { return 0; } virtual double run(double x) { return 0 && x; } virtual double run(double x,double y) { return 0 && x && y; } virtual double set(double &x,double y) { return 0 && x && y; } }; struct myValue:myFac { virtual double get() { return vlu; } }; struct myParam:myFac { virtual double get() { return *adr; } }; struct myOpr1p:myFac { virtual double run(double x) { switch(opr[0]) { case '+':return x; case '-':return -x; case '!':return x?0:1; case '#':return x?1:0; case '$':return x<0?-x:x; case '@':return x<0?-1:x>0?1:0; } return 0; } }; struct myFun1p:myFac { virtual double run(double x) { return fc1(x); } }; struct myOpr2p:myFac { virtual double run(double x,double y) { switch(opr[0]) { case '+':return x+y; case '-':return x-y; case '*':return x*y; case '/':return x/y; case '=':return x==y; case '!':return x!=y; case '&':return (bool)x && (bool)y; case '|':return (bool)x || (bool)y; case '>':return (opr[1]=='=')?(x>=y):(x>y); case '<':return (opr[1]=='=')?(x<=y):(x<y); } return 0; } }; struct myFun2p:myFac { virtual double run(double x,double y) { return fc2(x,y); } }; struct mySetvr:myFac { virtual double set(double x,double y) { switch(opr[0]) { case '=':x=y;break; case '+':x+=y;break; case '-':x-=y;break; case '*':x*=y;break; case '/':x/=y;break; } return x; } }; struct Atom { AtomType type; myFac *data; Atom *Lsun; Atom *Rsun; Atom() { type=Is_Empty; data=NULL; Lsun=NULL; Rsun=NULL; } ~Atom() { if(data)delete data; } }; void Remove(Atom *(&root)) { if(root) { Remove(root->Lsun); Remove(root->Rsun); delete root; root=NULL; } } struct Lequ { Atom *equ; Lequ *lst; Lequ *nxt; Lequ() { equ=NULL; lst=NULL; nxt=NULL; } ~Lequ() { if(equ)Remove(equ); } }; void Remove(Lequ *(&root)) { Lequ *sp,*md; sp=root; while(sp) { md=sp->nxt; delete sp; sp=md; } }