桌面计算器 ,可计算导数

本计算器采用LR分析,可支持CMATH.H库里的大部分运算,并且支持导数运算

 

#include <iostream> #include <vector> #include <string> #include <sstream> #include <stack> #include <queue> #include <cmath> #include <fstream> #define END "$" #define COL 11 #define ROW 20 #define ACCEPT "ac" #define PI 3.1415926 #define CHANGSHU_a "a" #define CHANGSHU_n "n" #define CHANGSHU_e "e" using namespace std; class Token { public: typedef double Value; typedef string Property; string name; Value sync; Property property; Token():sync(0.0){} Token(const string &s):name(s),property(s),sync(0.0) {} Token(const char* s):name(s),property(s),sync(0.0) {} friend bool operator ==(const Token& t1,const Token& t2); }; bool operator ==(const Token& t1,const Token& t2) { return t1.name==t2.name; } class LRpda//定义LL语法分析下推自动机 { typedef vector<Token> Engender;//定义产生式 typedef int State; typedef string Action; typedef struct eexpr//定义表达式 { Token uToken; Engender engender; }eExpr; public: LRpda(); bool Caculate(const string& exprtmp);//执行PDA bool Derivative(const string& exprtmp); private: bool in_propertys(Token::Property pro,vector<Token::Property> &pVec); bool is_unTerminateToken(const Token& token);//判断是否为非终结符 bool is_TerminateToken(const Token& token);//判断是否为终结符 bool is_delim(char ch); bool is_operator(char ch); bool is_letter(char ch); bool is_num(const string& str); bool is_num(const Token& token) {} bool is_id(const string& str); bool is_changshu(const string &str); double get_digit(char *&exprtmp); string get_operator(char *&exprtmp); void MatrixToFile(const char* filename); void get_propertys(const char* str,vector<Token::Property> &pVec); Token::Property get_property(const string& str); void addExpr(const Token& token,const Engender& engender);//添加产生式 void addExpr(const Token& token,const string& engender); void showMatrix();//打印LL语法分析表 void printExpr(const eExpr& expr); Token operate(const Token& t1,const Token& op,const Token& t2); Token operate(const Token& op,const Token& t1); string der_operate(const string& op,const string& t1); string LRpda::der_operate(const Token& t1,const string& d1,const string& op,const Token& t2,const string& d2); Action ACTION(const State state,const Token& ttoken);//返回 LL语法分析表中行为uToken,列为tToken中的元素 Action GOTO(const State state,const Token& utoken); private: State start; //开始符号 Token end; //结束符号 vector<Token::Property> uTokens;//非终结符号集 vector<Token::Property> tTokens;//终结符号集 vector<Token::Property> operator_1; vector<Token::Property> operator_2; vector<Token::Property> operator_3; vector<Token::Property> operator_4; vector<Token::Property> operator_5; vector<string> Error; vector<eExpr> eExprs;//表达式集合 stack<Token> tStack; stack<State> sStack; stack<Token::Value> vStack; stack<string> dStack; unsigned int uTokenCount;//非终结符号数量 unsigned int tTokenCount;//终结符号数量 string matrix[ROW][COL];//LL语法分析表 }; LRpda::LRpda() { //num id op1 op2 op3 op4 op5 ( ) $ E string copymatrix[ROW][COL]={ {"s5","s6","e1","e1","e1","s2","s3","s4","e2","e1","1" }, //0 {"s5","s6","s7","s8","s9","s2","s3","s4","e2","ac","10"}, //1 {"s5","s6","e1","e1","e1","s2","s3","s4","e2","e1","11"}, //2 {"s5","s6","e1","e1","e1","s2","s3","s4","e2","e1","12"}, //3 {"s5","s6","e1","e1","e1","s2","s3","s4","e2","e1","13"}, //4 {"r8","r8","r8","r8","r8","r8","r8","r8","r8","r8",""}, //5 {"r9","r9","r9","r9","r9","r9","r9","r9","r9","r9",""}, //6 {"s5","s6","e1","e1","e1","s2","s3","s4","e2","e1","14"}, //7 {"s5","s6","e1","e1","e1","s2","s3","s4","e2","e1","15"}, //8 {"s5","s6","e1","e1","e1","s2","s3","s4","e2","e1","16"}, //9 {"r6","r6","r6","r6","s9","r6","r6","r6","r6","r6","10"}, //10 {"s5","s6","s7","s8","s9","s2","s3","s4","e2","e1","17"}, //11 {"r5","r5","r5","r5","r5","r5","r5","r5","r5","r5",""}, //12 {"s5","s6","s7","s8","s9","s2","s3","s4","s18","e4","10"}, //13 {"s5","s6","r1","s8","s9","s2","s3","s4","r1","r1","10"}, //14 {"r2","r2","r2","r2","s9","r2","r2","r2","r2","r2","10"}, //15 {"r3","r3","r3","r3","s9","r3","r3","r3","r3","r3","10"}, //16 {"r4","r4","r4","r4","r4","r4","r4","r4","r4","r4","10"}, //17 {"r7","r7","r7","r7","r7","r7","r7","r7","r7","r7",""}}; //18 Token tTmp; string sTmp; int i,j; for(i=0;i<ROW;++i) for(j=0;j<COL;++j) matrix[i][j]=copymatrix[i][j]; get_propertys("num id op1 op2 op3 op4 op5 ( ) $ ",tTokens); get_propertys("E ",uTokens); get_propertys("+ -",operator_1); get_propertys("* /",operator_2); get_propertys("^",operator_3); get_propertys("log",operator_4); get_propertys("ln sin cos tan cot sec csc arcsin arccos arctan arccot sh ch th arsh arch arth ",operator_5); uTokenCount=uTokens.size(); tTokenCount=tTokens.size(); start=0; end=END; addExpr("E'","E"); //0 addExpr("E","E op1 E"); //1 addExpr("E","E op2 E"); //2 addExpr("E","E op3 E"); //3 addExpr("E","op4 E E"); //4 addExpr("E","op5 E"); //5 addExpr("E","E E"); //6 addExpr("E","( E )"); //7 addExpr("E","num"); //8 addExpr("E","id"); //9 Error.push_back("语法错误!"); Error.push_back("缺少运算分量!"); Error.push_back("不匹配的右括号!"); Error.push_back("缺少运算符!"); Error.push_back("缺少右括号!"); } void LRpda::MatrixToFile(const char* filename) { ofstream fout(filename),fout_t("martrix_tmp.txt"); int i,j; if(fout.good()) { fout<<"/t"; for(i=0;i<tTokenCount;++i) fout<<tTokens[i]<<"/t"; for(i=0;i<uTokenCount;++i) fout<<uTokens[i]<<"/t"; fout<<endl; for(i=0;i<ROW;++i) { fout<<i<<"/t"; for(j=0;j<COL;++j) fout<<matrix[i][j]<<"/t"; fout<<endl; } } for(i=0;i<ROW;++i) { fout_t<<"{"; for(j=0;j<COL-1;++j) fout_t<<"/""<<matrix[i][j]<<"/","; fout_t<<"/""<<matrix[i][j]<<"/""<<"},"<<endl; } fout_t.close(); fout.close(); } void LRpda::get_propertys(const char* str,vector<Token::Property> &pVec) { stringstream ss(str); string sTmp; while( ss>>sTmp) pVec.push_back(sTmp); } bool LRpda::in_propertys(Token::Property pro,vector<Token::Property> &pVec) { int i,size=pVec.size(); for(i=0;i<size;++i) if(pVec[i]==pro) return true; return false; } Token::Property LRpda::get_property(const string& str) { if(in_propertys(str,operator_1)) return "op1"; else if(in_propertys(str,operator_2)) return "op2"; else if(in_propertys(str,operator_3)) return "op3"; else if(in_propertys(str,operator_4)) return "op4"; else if(in_propertys(str,operator_5)) return "op5"; else if(is_num(str)) return "num"; else if(is_id(str)) return "id"; else if(str==")") return ")"; else if(str=="(") return "("; else if(str=="$") return "$"; else return ""; } bool LRpda::is_num(const string& str) { int state=0; char ch; bool flag=1; const char *exprtmp=str.c_str(); while((ch=*exprtmp)!=0 && flag) { switch(state) { case 0: if(ch=='+' || ch=='-') state=2; else if(isdigit(ch)) state=5; else flag=0; break; case 1: if(ch=='+' || ch=='-') state=4; else flag=0; break; case 2: if(isdigit(ch)) state=5; else flag=0; break; case 3: if(isdigit(ch)) state=6; else flag=0; break; case 4: if(isdigit(ch)) state=7; else flag=0; break; case 5: if(isdigit(ch)) state=5; else if(ch=='.') state=3; else if(ch=='e' || ch=='E') state=1; else flag=0; break; case 6: if(isdigit(ch)) state=6; else if(ch=='e' || ch=='E') state=1; else flag=0; break; case 7: if(isdigit(ch)) state=7; else flag=0; break; default: break; } ++exprtmp; } if(flag==1 && (state==5 || state==6 || state==7)) return true; return false; } bool LRpda::is_changshu(const string &str) { return (str==CHANGSHU_a || str==CHANGSHU_n || str==CHANGSHU_e ); } bool LRpda::is_letter(char ch) { ch|=0x20; if((ch>='a' && ch<='z')||ch=='_') return true; return false; } bool LRpda::is_id(const string &str) { int state=0; char ch; bool flag=1; const char *exprtmp=str.c_str(); while((ch=*exprtmp)!=0 && flag) { switch(state) { case 0: if(is_letter(ch)) state=1; else flag=0; break; case 1: if(is_letter(ch)||isdigit(ch)) state=1; else flag=0; break; default: break; } ++exprtmp; } if(flag==1 && state==1) return true; return false; } double LRpda::get_digit(char *&exprtmp) { int state=0; char ch; string digit; double resault=0.0; bool flag=1; while((ch=*exprtmp)!=0 && flag) { digit.push_back(ch); switch(state) { case 0: if(ch=='+' || ch=='-') state=2; else if(isdigit(ch)) state=5; else flag=0; break; case 1: if(ch=='+' || ch=='-') state=4; else flag=0; break; case 2: if(isdigit(ch)) state=5; else flag=0; break; case 3: if(isdigit(ch)) state=6; else flag=0; break; case 4: if(isdigit(ch)) state=7; else flag=0; break; case 5: if(isdigit(ch)) state=5; else if(ch=='.') state=3; else if(ch=='e' || ch=='E') state=1; else flag=0; break; case 6: if(isdigit(ch)) state=6; else if(ch=='e' || ch=='E') state=1; else flag=0; break; case 7: if(isdigit(ch)) state=7; else flag=0; break; default: break; } ++exprtmp; } if(flag==0) --exprtmp; if(state==5 || state==6 || state==7) sscanf(digit.c_str(),"%lf",&resault); return resault; } bool LRpda::is_delim(char ch) { return (ch==' '||ch=='/n' ||ch=='/t'); } bool LRpda::is_operator(char ch) { return (ch=='+'||ch=='-' ||ch=='*' ||ch=='/' || ch=='^'); } string LRpda::get_operator(char *&exprtmp) { char *tmp; int i=0; string sTmp; if(*exprtmp=='+') { ++exprtmp; return "+"; } else if(*exprtmp=='-') { ++exprtmp; return "-"; } else if(*exprtmp=='*') { ++exprtmp; return "*"; } else if(*exprtmp=='/') { ++exprtmp; return "/"; } else if(*exprtmp=='^') { ++exprtmp; return "^"; } else if(*exprtmp=='(') { ++exprtmp; return "("; } else if(*exprtmp==')') { ++exprtmp; return ")"; } tmp=exprtmp; while(*tmp!='/0' && i<3) { sTmp.push_back(*tmp); ++i; } if(sTmp=="sin" || sTmp== "cos") { exprtmp+=3; return sTmp; } return ""; } Token LRpda::operate(const Token& t1,const Token& op,const Token& t2) { Token t0; t0.name=t1.name+op.name+t2.name; if(t1.property=="num" && t2.property=="num") t0.property="num"; else { t0.property="id"; return t0; } switch(op.name[0]) { case '+': t0.sync=t1.sync+t2.sync; break; case '-': t0.sync=t1.sync-t2.sync; break; case '*': t0.sync=t1.sync*t2.sync; break; case '/': t0.sync=t1.sync/t2.sync; break; case '^': t0.sync=pow(t1.sync,t2.sync); break; default: break; } return t0; } Token LRpda::operate(const Token& op,const Token& t1) { Token t0; t0.name=op.name+t1.name; if(t1.property=="id") { t0.property="id"; } else if(t1.property=="num") { t0.property="num"; if(op.name=="sin") t0.sync=sin(t1.sync); else if(op.name=="cos") t0.sync=cos(t1.sync); else if(op.name=="tan") t0.sync=tan(t1.sync); else if(op.name=="cot") t0.sync=1.0/tan(t1.sync); else if(op.name=="sec") t0.sync=1.0/cos(t1.sync); else if(op.name=="csc") t0.sync=1.0/sin(t1.sync); else if(op.name=="arcsin") t0.sync=asin(t1.sync); else if(op.name=="arccos") t0.sync=acos(t1.sync); else if(op.name=="arctan") t0.sync=atan(t1.sync); else if(op.name=="arccot") t0.sync= PI/2.0-atan(t1.sync); else if(op.name=="ln") t0.sync=log(t1.sync); else if(op.name=="sh") t0.sync=sinh(t1.sync); else if(op.name=="ch") t0.sync=cosh(t1.sync); else if(op.name=="th") t0.sync=tanh(t1.sync); else cout<<"未定义的运算"<<endl; } return t0; } string LRpda::der_operate(const Token& t1,const string& d1,const string& op,const Token& t2,const string& d2) { string d0; char sbuf[32]={0}; Token t0; int nume,deno; string numerator,denominator,exp; unsigned int pos,pos0,pos1,pos2; if(t1.property=="num" && t2.property=="num") { t0=operate(t1,op,t2); sprintf(sbuf,"%g",t0.sync); return sbuf; } switch(op[0]) { case '+': if(d1=="0") d0=d2; else if(d2=="0") d0=d1; else d0=d1+op+d2; break; case '-': if(d1=="0") d0=op+d2; else if(d2=="0") d0=op+d1; else d0=d1+op+d2; break; case '*': if(t1.property=="num" && t2.property=="id") { if(d2=="1") d0=t1.name; else d0=t1.name+"*"+d2; } else if(t1.property=="id" && t2.property=="num") { if(d2=="1") d0=t1.name; else d0=t2.name+"*"+d1; } else if(is_changshu(t1.name) && t2.property=="id") { if(d2=="1") d0=t1.name; else d0=t1.name+"*"+d2; } else d0="("+d1+"*"+t2.name+"+"+d2+"*"+t1.name+")"; break; case '/': if(t1.name=="1") d0="(-1/"+t2.name+"^2)"; else d0="("+d1+"*"+t2.name+"-"+d2+"*"+t1.name+")"+"/"+t2.name+"^2"; break; case '^': if(t1.property=="id" && !is_changshu(t1.name) && t2.property=="id" && !is_changshu(t2.name)) { cout<<"未定义的导数运算!"<<endl; return ""; } if(t1.property=="id" && !is_changshu(t1.name)) { if( is_changshu(t2.name)) { d0=t2.name+t1.name+"^("+t2.name+"-1)"; } else if( t2.property=="num") { if((pos=t2.name.find("/"))!=string::npos) { if((pos0=t2.name.find("("))!=string::npos) pos1=pos0; else pos1=0; if((pos0=t2.name.find(")"))!=string::npos) pos2=pos0; else pos2=t2.name.size()-1; denominator=t2.name.substr(pos+1,pos2-pos-1); numerator=t2.name.substr(pos1+1,pos-pos1-1); deno=atoi(denominator.c_str()); nume=atoi(numerator.c_str()); nume-=deno; itoa(nume,sbuf,10); exp=sbuf+string("/")+denominator; d0=t2.name+t1.name+"^"+ "("+exp+")"; } else { if(t2.sync==2) { d0=t2.name+t1.name; } else { sprintf(sbuf,"%g",t2.sync-1); d0=t2.name+t1.name+"^"+sbuf ; } } } } else if(t2.property=="id") { if(is_changshu(t1.name)) { if(t1.name==CHANGSHU_e) d0=t1.name+"^"+t2.name; else d0=t1.name+"^"+t2.name+"ln"+t1.name; } else if(t1.property=="num" ) { d0=t1.name+"^"+t2.name+"ln"+t1.name; } } default: break; } return d0; } string LRpda::der_operate(const string& op,const string& t1) { string d0; if(op=="sin") d0="cos"+t1; else if(op=="cos") d0="(-sin"+t1+")"; else if(op=="tan") d0="(sec"+t1+")^2"; else if(op=="cot") d0="(-csc"+t1+")^2"; else if(op=="sec") d0="sec"+t1+"*tan"+t1; else if(op=="csc") d0="(-csc"+t1+"*cot"+t1+")"; else if(op=="arcsin") d0="1/(1-"+t1+"^2)^0.5"; else if(op=="arccos") d0="(-1/(1-"+t1+"^2)^0.5)"; else if(op=="arctan") d0="1/(1+"+t1+"^2)"; else if(op=="arccot") d0="(-1/(1+"+t1+"^2))"; else if(op=="ln") d0="1/"+t1; else if(op=="sh") d0="ch"+t1; else if(op=="ch") d0="sh"+t1; else if(op=="th") d0="1/(ch"+t1+"^2)"; else if(op=="arsh") d0="1/(1+"+t1+"^2)^(0.5)"; else if(op=="arch") d0="1/("+t1+"^2-1)^(0.5)"; else if(op=="arth") d0="1/(1-"+t1+"^2)"; return d0; } bool LRpda::Derivative(const string& exprtmp) { State state; Action action,actiontmp; Token token,token1,token2,token3,token0; stringstream eStream(exprtmp); Engender expr; int index=0,enlen,cur; Token::Value va,va1,va2; string sTmp; string der,der1,der2,der3,dersuffix,ds_tmp; char sbuf[32]={0}; int nume,deno; string numerator,denominator,exp; unsigned int pos,pos0,pos1,pos2; int expr_len=0; while(eStream>>sTmp) { token.name=sTmp; token.property=get_property(sTmp); if(token.property=="") { cout<<"未知字符 "<<token.name<<endl; return 0; } else if(token.property=="num") { sscanf(sTmp.c_str(),"%lf",&(token.sync)); } expr.push_back(token); ++expr_len; } state=start; token=expr[index++]; sStack.push(state); while(1) { action=ACTION(state,token); if(action[0]=='e') { actiontmp=action.substr(1,action.size()); state=atoi(actiontmp.c_str()); cout<<Error[state]<<endl; return 0; } else if(action[0]=='s') { actiontmp=action.substr(1,action.size()); state=atoi(actiontmp.c_str()); sStack.push(state); tStack.push(token); dStack.push(token.name); if(index >=expr_len) { cout<<"缺少终结符$!"<<endl; return 0; } token=expr[index++]; } else if(action[0]=='r') { actiontmp=action.substr(1,action.size()); cur=atoi(actiontmp.c_str()); switch(cur) { case 1: case 2: token3=tStack.top(); tStack.pop(); token2=tStack.top(); tStack.pop(); token1=tStack.top(); tStack.pop(); token0=operate(token1,token2,token3); tStack.push(token0); eExprs[cur].engender[1].name=token2.name; der3=dStack.top(); dStack.pop(); der2=dStack.top(); dStack.pop(); der1=dStack.top(); dStack.pop(); der=der_operate(token1,der1,der2,token3,der3); dStack.push(der); break; case 3: token3=tStack.top(); tStack.pop(); token2=tStack.top(); tStack.pop(); token1=tStack.top(); tStack.pop(); token0=operate(token1,token2,token3); tStack.push(token0); eExprs[cur].engender[1].name=token2.name; der3=dStack.top(); dStack.pop(); der2=dStack.top(); dStack.pop(); der1=dStack.top(); dStack.pop(); der=der_operate(token1,der1,der2,token3,der3); if(der=="") return 0; if(dersuffix.size()!=0) der=der+"*"+dersuffix; if((token.property=="op1" || token.property=="op2")) dersuffix.clear(); else dersuffix=der; dStack.push(der); break; case 4: token3=tStack.top(); tStack.pop(); token2=tStack.top(); tStack.pop(); token1=tStack.top(); tStack.pop(); token0=token1.name+token2.name+token3.name; tStack.push(token0); eExprs[cur].engender[0].name=token1.name; der3=dStack.top(); dStack.pop(); der2=dStack.top(); dStack.pop(); der1=dStack.top(); dStack.pop(); if(token2.property=="num" && token3.property=="id") { der="(1/"+token3.name+")*ln"+token2.name; } else if(is_changshu(token2.name) && token3.property=="id") { der="(1/"+token3.name+")*ln"+token2.name; } else { cout<<"未定义的导数运算!"<<endl; return 0; } if(dersuffix.size()!=0) der=der+"*"+dersuffix; if(token.property=="op1" || token.property=="op2") dersuffix.clear(); else dersuffix=der; dStack.push(der); break; case 5: token2=tStack.top(); tStack.pop(); token1=tStack.top(); tStack.pop(); token0=operate(token1,token2); tStack.push(token0); eExprs[cur].engender[0].name=token1.name; der2=dStack.top(); dStack.pop(); der1=dStack.top(); dStack.pop(); der=der_operate(token1.name,token2.name); if(dersuffix.size()!=0) der=der+"*"+dersuffix; if(token.property=="op1" || token.property=="op2") dersuffix.clear(); else dersuffix=der; dStack.push(der); break; case 6: token2=tStack.top(); tStack.pop(); token1=tStack.top(); tStack.pop(); token0=operate(token1,"*",token2); tStack.push(token0); der2=dStack.top(); dStack.pop(); der1=dStack.top(); dStack.pop(); der=der_operate(token1,der1,"*",token2,der2); dStack.push(der); break; case 7: token3=tStack.top(); tStack.pop(); token2=tStack.top(); tStack.pop(); token1=tStack.top(); tStack.pop(); if(is_changshu(token0.name)) token0.name=token2.name; else token0.name=token1.name+token2.name+token3.name; token0.sync=token2.sync; token0.property=token2.property; tStack.push(token0); der3=dStack.top(); dStack.pop(); der2=dStack.top(); dStack.pop(); der1=dStack.top(); dStack.pop(); der=der1+der2+der3; if(token2.property!="num") { if(token.property=="op1" || token.property=="op2") dersuffix.clear(); else dersuffix=der; } dStack.push(der); break; case 8: dStack.pop(); der="0"; dStack.push(der); break; case 9: der1=dStack.top(); dStack.pop(); if(is_changshu(der1)) der="0"; else der="1"; dStack.push(der); break; default:break; } enlen=eExprs[cur].engender.size(); while(enlen) { sStack.pop(); --enlen; } state=sStack.top(); action=GOTO(state,eExprs[cur].uToken); token0=tStack.top(); state=atoi(action.c_str()); sStack.push(state); token0=tStack.top(); } else if(action==ACCEPT) { cout<<"分析完毕!"<<endl; break; } else { cout<<"分析未完成!"<<endl; return 0; } } if(!dStack.empty()) { cout<<tStack.top().name<<": "<<dStack.top()<<endl; } return 1; } bool LRpda::Caculate(const string& exprtmp) { State state; Action action,actiontmp; Token token,token1,token2,token3,token0; stringstream eStream(exprtmp); Engender expr; int index=0,enlen,cur; Token::Value va,va1,va2; string sTmp; int expr_len=0; while(eStream>>sTmp) { token.name=sTmp; token.property=get_property(sTmp); if(token.property=="") { cout<<"未知字符 "<<token.name<<endl; return 0; } else if(token.property=="num") sscanf(sTmp.c_str(),"%lf",&(token.sync)); expr.push_back(token); ++expr_len; } state=start; token=expr[index++]; sStack.push(state); while(1) { action=ACTION(state,token); if(action[0]=='e') { actiontmp=action.substr(1,action.size()); state=atoi(actiontmp.c_str()); cout<<Error[state]<<endl; return 0; } else if(action[0]=='s') { actiontmp=action.substr(1,action.size()); state=atoi(actiontmp.c_str()); sStack.push(state); tStack.push(token); if(index >=expr_len) { cout<<"缺少终结符$!"<<endl; return 0; } token=expr[index++]; } else if(action[0]=='r') { actiontmp=action.substr(1,action.size()); cur=atoi(actiontmp.c_str()); switch(cur) { case 1: case 2: case 3: token3=tStack.top(); tStack.pop(); token2=tStack.top(); tStack.pop(); token1=tStack.top(); tStack.pop(); token0=operate(token1,token2,token3); tStack.push(token0); eExprs[cur].engender[1].name=token2.name; break; case 4: token3=tStack.top(); tStack.pop(); token2=tStack.top(); tStack.pop(); token1=tStack.top(); tStack.pop(); token0=token1.name+token2.name+token3.name; tStack.push(token0); cout<<"未定义的运算 "<<token1.name<<endl; eExprs[cur].engender[0].name=token1.name; return 0; case 5: token2=tStack.top(); tStack.pop(); token1=tStack.top(); tStack.pop(); token0=operate(token1,token2); tStack.push(token0); eExprs[cur].engender[0].name=token1.name; break; case 6: token2=tStack.top(); tStack.pop(); token1=tStack.top(); tStack.pop(); token0=operate(token1,"*",token2); tStack.push(token0); break; case 7: token3=tStack.top(); tStack.pop(); token2=tStack.top(); tStack.pop(); token1=tStack.top(); tStack.pop(); token0.name=token1.name+token2.name+token3.name; token0.sync=token2.sync; tStack.push(token0); break; case 9: token1=tStack.top(); cout<<"未知的变量"<<token1.name<<endl; return 0; default:break; } enlen=eExprs[cur].engender.size(); while(enlen) { sStack.pop(); --enlen; } state=sStack.top(); action=GOTO(state,eExprs[cur].uToken); token0=tStack.top(); state=atoi(action.c_str()); sStack.push(state); token0=tStack.top(); } else if(action==ACCEPT) { cout<<"计算完毕!"<<endl; break; } else { cout<<"计算未完成!"<<endl; return 0; } } if(!tStack.empty()) { token0=tStack.top(); cout<<token0.name<<"= "<<token0.sync<<endl; } return 1; } void LRpda::addExpr(const Token& token,const string& engender) { stringstream enStream(engender); Token tTmp; eExpr eTmp; string sTmp; eTmp.uToken=token; while(enStream>>sTmp) { tTmp.name=sTmp; tTmp.property=sTmp; eTmp.engender.push_back(tTmp); } eExprs.push_back(eTmp); } LRpda::Action LRpda::ACTION(const State state,const Token& ttoken) { int j; for(j=0;j<tTokenCount;++j) if(tTokens[j]==ttoken.property) break; if(j>=tTokenCount) return "e0"; return matrix[state][j]; } LRpda::Action LRpda::GOTO(const State state,const Token& utoken) { int j; for(j=0;j<uTokenCount;++j) if(uTokens[j]==utoken.property) break; if(j>=uTokenCount) return "e0"; return matrix[state][tTokenCount+j]; } void LRpda::showMatrix(void) { int i,j; cout<<" ACTION "<<" GOTO "<<endl; cout<<"/t"; for(i=0;i<tTokenCount;++i) cout<<tTokens[i]<<"/t"; for(i=0;i<uTokenCount;++i) cout<<uTokens[i]<<"/t"; cout<<endl; for(i=0;i<ROW;++i) { cout<<i<<"/t"; for(j=0;j<COL-1;++j) { cout<<matrix[i][j]<<"/t"; } cout<<matrix[i][j]<<endl; } } void LRpda::printExpr(const eExpr& expr) { int i; cout<<expr.uToken.name<<"-->"; for(Engender::const_iterator it=expr.engender.begin();it!=expr.engender.end();++it) cout<<it->name; cout<<endl; } int get_choice(void) { int choice; string str; cin>>choice; cin.clear(); cin.ignore(); while(choice>4 || choice<1) { cout<<"请输入数字 1,2,3,4:"; cin>>choice; cin.clear(); cin.ignore(); } return choice; } void print_menu(void) { cout<<"***********************************"<<endl; cout<<"1, 桌面计算器"<<endl; cout<<"2, 计算导数"<<endl; cout<<"3, 使用说明"<<endl; cout<<"4, 退出"<<endl; cout<<"***********************************"<<endl; cout<<"请输入数字1,2,3,4选择相应功能:"<<endl; } void menu(void) { int choice; LRpda lrpda; string expr; print_menu(); while((choice=get_choice())!=4) { if(choice==1) { cout<<"你选择的是计算器,请输入表达式: "<<endl; getline(cin,expr); expr=expr+" "+END; lrpda.Caculate(expr); cout<<"继续输入数字1,2,3,4选择相应功能:"<<endl; } else if(choice==2) { cout<<"你选择的是计算导数,请输入表达式: "<<endl; getline(cin,expr); expr=expr+" "+END; lrpda.Derivative(expr); cout<<"继续输入数字1,2,3,4选择相应功能:"<<endl; } else if(choice==3) { system("cls"); cout<<"***************************************使用说明*********************************/n"<<endl; cout<<"1、输入表达式时,数字和数字之间、数字和算符(括号)之间要键入空格,不然无法正确分析计算,例如,sinx会被视为一个变量,正确形式为sin x"<<endl; cout<<" 需要输入负数时如 x ^ ( - 2 ),可以输入为 x ^ ( 0 - 2 ) 的形式,其他运算都是如此"<<endl; cout<<" 遇到复杂的表达式,如 e ^ ( sin x ) ^ 2 + x ,需要添加括号,e ^ ( ( sin x ) ^ 2 ) + x , 再如 sin sin x + cos cos x 需写为( sin sin x ) + cos cos x ,以取得正确结果" <<endl; cout<<" 支持数学表达式中的乘法简写,如 a * b 可简写为 a b" <<endl; cout<<"2、计算器支持的运算为:+,-,*,/,^(次方运算),sin,cos,tan,cot,sec,csc,arcsin,arccos,arctan,arccot,sh,ch,th,ln,暂不支持对数LOG运算,"<<endl; cout<<" 运算符的优先级和数学中相同,即 sin ... > ^ > *// > +/- ,可通过添加括号改变优先级" <<endl; cout<<" 采用浮点型(double)数值计算,暂不支持大数运算,所以需要注意浮点型数值精度问题"<<endl; cout<<"3、导数支持的运算为:+,-,*,/,^,sin,cos,tan,cot,sec,csc,arcsin,arccos,arctan,arccot,sh,ch,th,ln,log"<<endl; cout<<" 不支持如下形式:x^x(底数和指数都为变量) log x 2 (底数为变量)"<<endl; cout<<" 默认 a、e(ln的底数)、n为常数,两变量间无符号默认为乘法(*)运算(log除外)"<<endl; cout<<" 导数最后得到的结果可能会出现1*x、sinx/cosx 之类的形式,需要自己进行化简"<<endl; cout<<"/n********************************************************************************"<<endl; cout<<"继续输入数字1,2,3,4选择相应功能:"<<endl; } } cout<<"谢谢使用,再见!"<<endl; } int main(void) { menu(); getchar(); return 0; }

 

你可能感兴趣的:(String,iterator,action,token,Matrix,menu)