表达式解析计算器源码(完整实现)
发布时间:2020-12-14 02:48:48 所属栏目:大数据 来源:网络整理
导读:大一下时做的大数非图形界面计算器,自己在这个过程中收获较大,希望和大家分享下 分三个(面向过程浮点版,面向对象浮点版和面向对象大数版)版本:: 完整实现如下: Version1: 面向过程浮点版 (从文件读入并输出) divexcept.h(存储各种错误信息) #inclu
大一下时做的大数非图形界面计算器,自己在这个过程中收获较大,希望和大家分享下 分三个(面向过程浮点版,面向对象浮点版和面向对象大数版)版本:: 完整实现如下: Version1: 面向过程浮点版 (从文件读入并输出) divexcept.h(存储各种错误信息) #include <iostream> #include <string> using namespace std; string return_except(int sign) { string errortype; if(sign==1)errortype="运算符错位/(Primary Expected)"; else if(sign==2)errortype="多余运算符/(Unexpected Token)"; else if(sign==3)errortype="出现非法字符/(Invalid Characters)"; else if(sign==4)errortype="右括号多于左括号/(Too Many Right Parentheses)"; else if(sign==5)errortype="变量名命名错误/(Unexpected Token)"; else if(sign==6)errortype="除零错误/(Divide By Zero)"; else if(sign==7)errortype="变量名过长/(Too Long Name Of Variables)"; else if(sign==8)errortype="未定义变量/(Undefined Variables)"; else if(sign==9)errortype="乘号缺失/(Multiple Sign Expected)"; else if(sign==10)errortype="左右括号不匹配/(Parentheses Matching failed)"; return errortype; } #include <iostream> #include <string> #include <map> using namespace std; string validchars="0123456789*/+-=()_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ "; string tmp=""; int precheck(string s) { int count=0; tmp=""; int sign=0;//因错误类型繁多,故设定sign值为0时,判断无错误。 int leftp=0,rightp=0;//分别表示左右括号数。 s=' '+s;//便于后续过程处理 int len=s.length(); //报错类型1,运算符错位,(Primary Expected),括号内的独立表达式会在下述循环中处理 。 if(s[1]=='*'||s[1]=='/'||s[1]=='=') { sign=1; return sign; } //报错类型2,多余运算符,(Unexpected Token),式子中的将在循环中处理。 if(s[len-1]=='+'||s[len-1]=='*'||s[len-1]=='/'||s[len-1]=='-'||s[len-1]=='=') { sign=2; return sign; } for(int i=1;i<s.length();i++) { //报错类型3,合法字符中找不到该字符,(Bad Token)。 if(validchars.find(s[i])==-1) { sign=3; return sign; } if(s[i]=='(')leftp++; else if(s[i]==')')rightp++; //报错类型4,右括号多于左括号,(Too Many Right Parentheses)。 if(rightp>leftp) { sign=4; return sign; } //报错类型5,变量名命名错误,数字后不能再跟字母,(Unexpected Token)。 if(isalpha(s[i])&&isdigit(s[i-1])) { sign=5; return sign; } //报错类型6,除零错误,此处只能初判直接除以0的错误,运算中将继续检查(Divide By Zero)。 if(s[i-1]=='/'&&s[i]=='0') { sign=6; return sign; } //报错类型1,运算符错位,(Priamry Expected)。 if((s[i-1]=='+'||s[i-1]=='-'||s[i-1]=='*'||s[i-1]=='/'||s[i-1]=='=') &&(s[i]=='+'||s[i]=='-'||s[i]=='*'||s[i]=='/'||s[i]=='=')) { sign=1; return sign; } if((s[i-1]=='(')&&(s[i]=='='||s[i]=='*'||s[i]=='/')) { sign=1; return sign; } //报错类型2,多余运算符,(Unexpected Token)。 if((s[i]==')')&&(s[i-1]=='='||s[i-1]=='+'||s[i-1]=='-'||s[i-1]=='*'||s[i-1]=='/')) { sign=2; return sign; } //报错类型9,不能省略乘号,(Multiple Sign Can't Be Ignored)。 if((s[i]=='('&&isalnum(s[i-1]))||(s[i-1]==')'&&isalnum(s[i]))) { sign=9; return sign; } //统计=号个数 if(s[i]=='=')count++; } //左右括号不匹配,报错类型10(Parentheses Matching failed)。 if(leftp!=rightp) { sign=10; return sign; } if(count)//代表是赋值表达式,处理全是数字的变量错误 { int count1=0; s[0]='='; //将表达式变成 =123=234从而方便判断 for(int i=1;i<s.length();i++) { if(s[i]=='=')count1++; if(s[i]<='9'&&s[i]>='0'&&s[i-1]=='='&&count1!=count) { sign=5; return sign; } } } return sign; } #include <fstream> #include <iostream> #include <map> #include <string> #include <iomanip> #include "divexcept.h" #include "pre_check.h" using namespace std; double term(),factor(),expr(),number(); void assignment(); string var(),original,store;//original为预处理后的表达式 int pos;//pos计算过程中的光标位置 map <string,double> vars;//储存变量 int presign=0;//预判过程中的错误标记,0默认无错误 int tmpsign=0;//文法解析过程中的错误标记,0默认无错误 ifstream in("in.txt"); ofstream out("out.txt"); void assignment() { //如若已出错,直接返回 if(tmpsign) return; string varName[20]; //最多支持20个变量的连等 double val; int n=0; while(1) { int var_begin=pos; if(isalpha(original[pos])||original[pos]=='_') //表示读入变量名 { string temp=var(); if(temp!="") varName[n++]=temp;//""代表出现过长变量名,已处理 else break; if(pos!=original.length()-1&&original[pos]=='=') ++pos; else { pos=var_begin; //变量名后面不再是等号,把变量名回吐 n--; break; } } else break;//已读不到变量名 } val=expr(); if(!tmpsign)//代表没有出现任何异常 { for(int i=0;i<n;i++) vars[varName[i]]=val;//把变量及值放入map out<<"Assignment Succeed!/赋值成功n"; for(int i=0;i<n;i++)out<<varName[i]<<": "<<vars[varName[i]]<<" "; out<<endl; return ; } else return; } double expr(void) { //如若已出错,直接返回 if(tmpsign) return 0; double result_expr; //若出现其它运算符,已在预判中报错 if(original[pos]=='-'){ ++pos;result_expr=-term();} else result_expr=term(); while(1) { if(original[pos]=='+') { ++pos; result_expr+=term(); } else if(original[pos]=='-') { ++pos; result_expr-=term(); } else break; } return result_expr; } double term(void) { //如若已出错,直接返回 if(tmpsign) return 0; double result_term=factor(); while(1) { if(original[pos]=='*') { ++pos; result_term*=factor(); } else if(original[pos]=='/') { ++pos; double temp=1.0*factor();//除法特殊处理 if(temp==0.0) { tmpsign=6; return 0; } else result_term/=temp; } else break; } return result_term; } double factor(void) { //如若已出错,直接返回 if(tmpsign) return 0; double result_factor; if(original[pos]=='(') { ++pos; //跳过左括号 //flag=1; if(original[pos]=='_'||isalpha(original[pos])) assignment(); //赋值表达式 else result_factor=expr();//普通表达式 ++pos; //跳过右括号,右括号异常已在预判中处理 //flag=0; } else if(isdigit(original[pos])) result_factor=number(); else if(original[pos]=='_'||isalpha(original[pos])) { string vn=var();//取变量名 map<string,double>::iterator it; it=vars.find(vn); if(it!=vars.end())result_factor= it->second; //报错类型8,未定义变量,通过tmpsign反映出错,计算仍将继续 else {tmpsign=8;return 0;} } //报错类型2,Unexpected Token。 else {tmpsign=2;return 0;} return result_factor; } double number(void) { //如若已出错,直接返回 if(tmpsign) return 0; double num=0; while(isdigit(original[pos])) { num=10.0*num+(original[pos]-'0'); ++pos; } return num; } string var(void) { //如若已出错,直接返回 if(tmpsign) return ""; string varName; int n=0; if(original[pos]=='_'||isalpha(original[pos])) varName+=original[pos++]; while(original[pos]=='_'||isalnum(original[pos])) varName+=original[pos++]; //变量名过长,报错类型7,将变量名置为空,代表赋值不成功 if(varName.length()>20) { tmpsign=7; varName=""; } return varName; } int main() { while(getline(in,store)) { int is_assignment=0; //original初始化 original=""; for(int i=0;i<store.size();i++)// 支持空格读入 { if(store[i]!=' ') original+=store[i]; } pos=0; tmpsign=0;//默认无错 presign=precheck(original);// 先进行简单错误的预判 if(!presign) { double ans=0; if(original.find('=')!=-1)//判断是否为表达式,此处只区分赋值和非赋值表达式 { assignment(); is_assignment=1; } else ans=expr(); if(!tmpsign&&!is_assignment)out<<"The result of ("<<original<<") is: "<<fixed<<setprecision(6)<<ans<<endl; else if(tmpsign)out<<return_except(tmpsign)<<endl; } else out<<return_except(presign)<<endl; } return 0; } Version2: 面向对象浮点版 divexcept.h与except.h与上同 programm.h(解析头文件) #include <string> #include <map> #include <fstream> using namespace std; class Program { int presign;//预判过程中的错误标记,0默认无错误 int tmpsign;//文法解析过程中的错误标记,0默认无错误 int pos;//pos计算过程中的光标位置 string original,store;//original为预处理后的表达式 map <string,double> vars;//储存变量 public: Program() { ifstream in("in.txt"); ofstream out("out.txt"); }; void run(); double term(),number(); void assignment(); string var(); }; programm.cpp(解析具体实现) #include <fstream> #include <iostream> #include <map> #include <string> #include <iomanip> #include "divexcept.h" #include "pre_check.h" #include "program.h" using namespace std; ifstream in("in.txt"); ofstream out("out.txt"); void Program:: assignment() { //如若已出错,直接返回 if(tmpsign) return; string varName[20]; //最多支持20个变量的连等 double val; int n=0; while(1) { int var_begin=pos; if(isalpha(original[pos])||original[pos]=='_') //表示读入变量名 { string temp=var(); if(temp!="") varName[n++]=temp;//""代表出现过长变量名,已处理 else break; if(pos!=original.length()-1&&original[pos]=='=') ++pos; else { pos=var_begin; //变量名后面不再是等号,把变量名回吐 n--; break; } } else break;//已读不到变量名 } val=expr(); if(!tmpsign)//代表没有出现任何异常 { for(int i=0;i<n;i++) vars[varName[i]]=val;//把变量及值放入map out<<"Assignment Succeed!/赋值成功n"; for(int i=0;i<n;i++)out<<varName[i]<<": "<<vars[varName[i]]<<" "; out<<endl; return ; } else return; } double Program:: expr(void) { //如若已出错,直接返回 if(tmpsign) return 0; double result_expr; //若出现其它运算符,已在预判中报错 if(original[pos]=='-'){ ++pos;result_expr=-term();} else result_expr=term(); while(1) { if(original[pos]=='+') { ++pos; result_expr+=term(); } else if(original[pos]=='-') { ++pos; result_expr-=term(); } else break; } return result_expr; } double Program:: term(void) { //如若已出错,直接返回 if(tmpsign) return 0; double result_term=factor(); while(1) { if(original[pos]=='*') { ++pos; result_term*=factor(); } else if(original[pos]=='/') { ++pos; double temp=1.0*factor();//除法特殊处理 if(temp==0.0) { tmpsign=6; return 0; } else result_term/=temp; } else break; } return result_term; } double Program:: factor(void) { //如若已出错,直接返回 if(tmpsign) return 0; double result_factor; if(original[pos]=='(') { ++pos; //跳过左括号 //flag=1; if(original[pos]=='_'||isalpha(original[pos])) assignment(); //赋值表达式 else result_factor=expr();//普通表达式 ++pos; //跳过右括号,右括号异常已在预判中处理 //flag=0; } else if(isdigit(original[pos])) result_factor=number(); else if(original[pos]=='_'||isalpha(original[pos])) { string vn=var();//取变量名 map<string,Unexpected Token。 else {tmpsign=2;return 0;} return result_factor; } double Program:: number(void) { //如若已出错,直接返回 if(tmpsign) return 0; double num=0; while(isdigit(original[pos])) { num=10.0*num+(original[pos]-'0'); ++pos; } return num; } string Program:: var(void) { //如若已出错,直接返回 if(tmpsign) return ""; string varName; int n=0; if(original[pos]=='_'||isalpha(original[pos])) varName+=original[pos++]; while(original[pos]=='_'||isalnum(original[pos])) varName+=original[pos++]; //变量名过长,报错类型7,将变量名置为空,代表赋值不成功 if(varName.length()>20) { tmpsign=7; varName=""; } return varName; } void Program:: run() { while(getline(in,store)) { presign=0; int is_assignment=0; //original初始化 original=""; for(int i=0;i<store.size();i++)// 支持空格读入 { if(store[i]!=' ') original+=store[i]; } pos=0; tmpsign=0;//默认无错 presign=precheck(original);// 先进行简单错误的预判 if(!presign) { double ans=0; if(original.find('=')!=-1)//判断是否为表达式,此处只区分赋值和非赋值表达式 { assignment(); is_assignment=1; } else ans=expr(); if(!tmpsign&&!is_assignment)out<<"The result of ("<<original<<") is: "<<fixed<<setprecision(6)<<ans<<endl; else if(tmpsign)out<<return_except(tmpsign)<<endl; } else out<<return_except(presign)<<endl; } } main.cpp #include"program.h" using namespace std; int main() { Program loader; loader.run(); } Version3 面向对象大数版 divexcept.h与pre_check.h与上同 programm.h #include <string> #include <map> #include <fstream> #include "BigNum.h" using namespace std; class Program { int presign;//预判过程中的错误标记,0默认无错误 int tmpsign;//文法解析过程中的错误标记,0默认无错误 int pos;//pos计算过程中的光标位置 string original,string> vars;//储存变量 public: Program() { ifstream in("in.txt"); ofstream out("out.txt"); }; void run(); BigNum term(),number(); void assignment(); string var(); }; #ifndef PROGRAM #define PROGRAM #include <fstream> #include <iostream> #include <map> #include <string> #include <iomanip> #include "divexcept.h" #include "pre_check.h" #include "program.h" using namespace std; ifstream in("in.txt"); ofstream out("out.txt"); void Program:: assignment() { //如若已出错,直接返回 if(tmpsign) return; string varName[20]; //最多支持20个变量的连等 BigNum val(0); int n=0; while(1) { int var_begin=pos; if(isalpha(original[pos])||original[pos]=='_') //表示读入变量名 { string temp=var(); if(temp!="") varName[n++]=temp;//""代表出现过长变量名,已处理 else break; if(pos!=original.length()-1&&original[pos]=='=') ++pos; else { pos=var_begin; //变量名后面不再是等号,把变量名回吐 n--; break; } } else break;//已读不到变量名 } val=expr(); if(!tmpsign)//代表没有出现任何异常 { for(int i=0;i<n;i++) vars[varName[i]]=val.get_total();//把变量及值放入map out<<"Assignment Succeed!/赋值成功n"; for(int i=0;i<n;i++)out<<varName[i]<<": "<<vars[varName[i]]<<" "; out<<endl; return ; } else return; } BigNum Program:: expr(void) { //如若已出错,直接返回 if(tmpsign) return (BigNum)0; BigNum result_expr(0); //若出现其它运算符,已在预判中报错 if(original[pos]=='-'){ ++pos;result_expr-=term();} else result_expr=term(); while(1) { if(original[pos]=='+') { ++pos; result_expr+=term(); } else if(original[pos]=='-') { ++pos; result_expr-=term(); } else break; } return result_expr; } BigNum Program:: term(void) { //如若已出错,直接返回 if(tmpsign) return (BigNum)0; BigNum result_term=factor(); while(1) { if(original[pos]=='*') { ++pos; result_term*=factor(); } else if(original[pos]=='/') { ++pos; BigNum temp=factor();//除法特殊处理 if(temp==0) { tmpsign=6; return (BigNum)0; } else result_term=result_term/temp; } else if(original[pos]=='%') { ++pos; BigNum temp=factor(); if(temp==0) { tmpsign=11; return (BigNum)0; } } else break; } return result_term; } BigNum Program:: factor(void) { string temp1; //如若已出错,直接返回 if(tmpsign) return (BigNum)0; BigNum result_factor(0); if(original[pos]=='(') { ++pos; //跳过左括号 //flag=1; if(original[pos]=='_'||isalpha(original[pos])) assignment(); //赋值表达式 else result_factor=expr();//普通表达式 ++pos; //跳过右括号,右括号异常已在预判中处理 //flag=0; } else if(isdigit(original[pos])) result_factor=number(); else if(original[pos]=='_'||isalpha(original[pos])) { string vn=var();//取变量名 map<string,string>::iterator it; it=vars.find(vn); if(it!=vars.end()) { temp1=it->second; result_factor=(BigNum)temp1; } //报错类型8,未定义变量,通过tmpsign反映出错,计算仍将继续 else {tmpsign=8;return(BigNum) 0;} } //报错类型2,Unexpected Token。 else {tmpsign=2;return (BigNum)0;} return result_factor; } BigNum Program:: number(void) { //如若已出错,直接返回 if(tmpsign) return (BigNum)0; BigNum num(0); while(isdigit(original[pos])) { num=(BigNum)10*num+(original[pos]-'0'); ++pos; } return num; } string Program:: var(void) { //如若已出错,直接返回 if(tmpsign) return ""; string varName; int n=0; if(original[pos]=='_'||isalpha(original[pos])) varName+=original[pos++]; while(original[pos]=='_'||isalnum(original[pos])) varName+=original[pos++]; //变量名过长,报错类型7,将变量名置为空,代表赋值不成功 if(varName.length()>20) { tmpsign=7; varName=""; } return varName; } void Program:: run() { while(getline(in,store)) { presign=0; int is_assignment=0; //original初始化 original=""; for(int i=0;i<store.size();i++)// 支持空格读入 { if(store[i]!=' ') original+=store[i]; } pos=0; tmpsign=0;//默认无错 presign=precheck(original);// 先进行简单错误的预判 if(!presign) { BigNum ans(0); if(original.find('=')!=-1)//判断是否为表达式,此处只区分赋值和非赋值表达式 { assignment(); is_assignment=1; } else ans=expr(); if(!tmpsign&&!is_assignment)out<<"The result of ("<<original<<") is: "<<fixed<<setprecision(6)<<ans<<endl; else if(tmpsign)out<<return_except(tmpsign)<<endl; } else out<<return_except(presign)<<endl; } } #endif 大数类定义实现: Bignum.h #ifndef BIGNUM_HEADER #define BIGNUM_HEADER #include<iostream> using namespace std; class BigNum{ int _sign;//0表示没有负号,1表示有负号 string _num; public: BigNum(const string& a = "0" ); BigNum(const int &x=0); friend BigNum operator+( const BigNum& a,const BigNum& b ); friend BigNum operator-( const BigNum& a,const BigNum& b ); friend BigNum operator*( const BigNum& a,const BigNum& b ); friend BigNum operator/( const BigNum& a,const BigNum& b ); friend BigNum operator%( const BigNum& a,const BigNum& b ); string get_total() { return (_sign==1?"-":"")+_num; } BigNum& operator+=(const BigNum& a){ return *this = *this + a; } BigNum& operator-=(const BigNum& a){ return *this = *this - a; } BigNum& operator*=(const BigNum& a){ return *this = *this * a; } BigNum& operator/=(const BigNum& a){ return *this = *this / a; } BigNum& operator%=(const BigNum& a){ return *this = *this / a; } friend bool operator==(const BigNum& a,const BigNum& b); friend istream& operator>>(istream& in,BigNum& a); friend ostream& operator<<(ostream& out,const BigNum& a); };//----------------------------------- #endif BigNum.cpp #ifndef BIGNUM2 #define BIGNUM2 #include "BigNum.h" #include <string> #include <string.h> string add(string a,string b); string sub(string a,string b); string div(string a,string b); string mult(string a,string b); string cal(string a,string b); string mod(string a,string b); //------------------------------------- BigNum::BigNum(const string& a)//构造函数 { if(a[0]=='-') { _sign=1; _num=a.substr(1); } else { _sign=0; _num=a; } }//------------------------------------ BigNum::BigNum(const int& x)//构造函数 { string tmp=""; if(x==0)tmp="0"; int temp; if(x<0)_sign=1; else _sign=0; temp=abs(x); while(temp) { tmp+=(temp%10+'0'); temp/=10; } reverse(tmp.begin(),tmp.end()); _num=tmp; }//------------------------------------ bool comp(string a,string b) { if(a.length()<b.length())return true; else if(a.length()>b.length())return false; else { bool flag=0; for(int i=0;i<a.length();i++) { if(a[i]<b[i])return true; else if(a[i]>b[i])return false; } return flag;//a==b } } BigNum operator+( const BigNum& a,const BigNum& b ) { string tmp1=a._num,tmp2=b._num,ans; if(a._sign==1)tmp1='-'+tmp1; if(b._sign==1)tmp2='-'+tmp2; ans=cal(tmp1,tmp2); BigNum ret(ans); return ret; }//------------------------------------ BigNum operator-( const BigNum& a,const BigNum& b ) { string tmp1=a._num,ans; tmp2='-'+tmp2; if(a._sign==1)tmp1='-'+tmp1; ans=cal(tmp1,tmp2); BigNum ret(ans); return ret; }//------------------------------------ BigNum operator*( const BigNum& a,ans; ans=mult(tmp1,tmp2); if(!((a._sign==1&&b._sign==1)||(a._sign==0&&b._sign==0))) ans='-'+ans; BigNum ret(ans); return ret; }//------------------------------------ BigNum operator/( const BigNum& a,ans; ans=div(tmp1,tmp2); if((a._sign&&!b._sign)||(!a._sign&&b._sign)) ans='-'+ans; BigNum ret(ans); return ret; }//------------------------------------*/ BigNum operator%( const BigNum& a,ans; ans=mod(tmp1,tmp2); BigNum ret(ans); return ret; }//------------------------------------*/ istream& operator>>(istream& in,BigNum& a) { string s; in>>s; a = BigNum(s); return in; }//------------------------------------ ostream& operator<<(ostream& out,const BigNum& a) { return out<<(a._sign?"-":"") << a._num; }//------------------------------------ bool operator==(const BigNum& a,const BigNum& b) { return a._sign==b._sign && a._num==b._num; }//------------------------------------ //---------------------------------------- string add(string s1,string s2) { reverse(s1.begin(),s1.end());//反转 reverse(s2.begin(),s2.end()); s1+=string(205-s1.length(),'0');//补0 s2+=string(205-s2.length(),'0'); int flag=0,p; for(int i=0;i<205;i++) { s1[i]=flag+s1[i]+s2[i]-'0';//加法计算过程 if(s1[i]>'9'){ s1[i]-=10; flag=1;} else flag=0; } reverse(s1.begin(),s1.end());//再反回来 p=s1.find_first_not_of('0');//去除多余的0 if(p!=-1) s1=s1.substr(p); else s1="0"; return s1; } //---------------------------------------------------------- string sub(string s1,string s2) { int sign,l1,l2,symbol;//sign表运算正负性,symbol表s1,s2长度 string tmp1,tmp2; if(s1[0]=='-') { tmp1=s1.substr(1); tmp2=s2; if(tmp1.length()>tmp2.length())sign=0; else if(tmp2.length()>tmp1.length())sign=1; else { sign=1;//如果两数刚好相等,那么默认不需'-'号 for(int i=0;i<tmp1.length();i++) { if(tmp1[i]>tmp2[i]){sign=0;symbol=0;break;} else if(tmp1[i]<tmp2[i]){sign=1;symbol=1;break;} } } } else { tmp1=s1; tmp2=s2.substr(1); if(tmp1.length()>tmp2.length())sign=1; else if(tmp2.length()>tmp1.length())sign=0; else { sign=1;//如果两数刚好相等,那么默认不需'-'号 for(int i=0;i<tmp1.length();i++) { if(tmp1[i]>tmp2[i]){sign=1;symbol=0;break;} else if(tmp1[i]<tmp2[i]){sign=0;symbol=1;break;} } } } reverse(tmp1.begin(),tmp1.end()); reverse(tmp2.begin(),tmp2.end()); l1=tmp1.length(); l2=tmp2.length(); tmp1+=string(205-tmp1.length(),'0'); tmp2+=string(205-tmp2.length(),'0'); int flag=0; if(l1>l2) { for(int i=0;i<l1;i++) { tmp1[i]=tmp1[i]-tmp2[i]+'0'+flag;//减法计算过程 if(tmp1[i]<'0') { tmp1[i]=tmp1[i]+10; flag=-1; } else flag=0; } } else if(l2>l1) { for(int i=0;i<l2;i++) { tmp1[i]=tmp2[i]-tmp1[i]+'0'+flag; if(tmp1[i]<'0') { tmp1[i]=tmp1[i]+10; flag=-1; } else flag=0; } } else { if(symbol) { for(int i=0;i<l1;i++) { tmp1[i]=tmp2[i]-tmp1[i]+'0'+flag; if(tmp1[i]<'0') { tmp1[i]=tmp1[i]+10; flag=-1; } else flag=0; } } else { for(int i=0;i<l1;i++) { tmp1[i]=tmp1[i]-tmp2[i]+'0'+flag; if(tmp1[i]<'0') { tmp1[i]=tmp1[i]+10; flag=-1; } else flag=0; } } } reverse(tmp1.begin(),tmp1.end()); int p=tmp1.find_first_not_of('0'); if(p!=-1) tmp1=tmp1.substr(p); else tmp1="0"; if(sign)return tmp1; else return '-'+tmp1; } //------------------------------------------------ string cal(string s1,string s2) { if(s1[0]=='-'&&s2[0]=='-') { string tmp1,tmp2; tmp1=s1.substr(1); tmp2=s2.substr(1); s1='-'+add(tmp1,tmp2); } else if(s1[0]!='-'&&s2[0]!='-') { s1=add(s1,s2); } else { s1=sub(s1,s2); } return s1; } //-------------------------------------------- string mult(string x,string y) { int ans[420],a[205],b[205]; int flag=0; memset(ans,sizeof(ans)); memset(a,sizeof(a)); memset(b,sizeof(b)); reverse(x.begin(),x.end());//反转 最低位对齐 reverse(y.begin(),y.end()); for(int i=0;i<x.length();i++)a[i]=x[i]-'0';//转成数字 for(int i=0;i<y.length();i++)b[i]=y[i]-'0'; for(int i=0;i<205;i++) { for(int j=0;j<205;j++) { ans[i+j]=ans[i+j]+a[i]*b[j];//列式累加,进位之后处理 } } for(int i=0;i<420;i++) { ans[i]=ans[i]+flag;//进位处理 flag=ans[i]/10; ans[i]%=10; } int p=0; for(int i=419;i>=0;i--) { if(ans[i]!=0) { p=i; break; } } string tmp=""; for(int i=p;i>=0;i--) tmp+=(ans[i]+'0'); return tmp; } string div(string a,string b) { if(a.length()<b.length())return "0"; else if(a==b) return "1"; else if(a.length()==b.length()) { if(comp(a,b))return "0"; else { int count=0; string tmp5,tmp6; tmp6='-'+b; while(1) { if(comp(a,b))break; a=cal(a,tmp6); count++; } if(count==0)tmp5="0"; while(count) { tmp5+=(count%10+'0'); count/=10; } reverse(tmp5.begin(),tmp5.end()); return tmp5; } } else { int l=a.length()-b.length(),count=0; string tmp,tmp1,tmp2,tmp3="",tmp7;//假设最大除以999... if(l!=0)tmp=a.substr(0,l); else tmp="0"; tmp1=mult(tmp,b); tmp1='-'+tmp1; tmp2=sub(a,tmp1); tmp7='-'+b; while(1) { if(comp(tmp2,b))break;//判定tmp2是否小于b else { tmp2=sub(tmp2,tmp7); count++; //用count计数,等会再转为string } } if(count==0)tmp3="0"; while(count) { tmp3+=(count%10+'0'); count/=10; } reverse(tmp3.begin(),tmp3.end()); tmp=add(tmp,tmp3); return tmp; } } string mod(string a,string b) { if(a.length()<b.length())return a; else if(a==b) return "0"; else if(a.length()==b.length()) { if(comp(a,b))return a; else { string tmp5,tmp6); } return a; } } else { int l=a.length()-b.length(),tmp7); count++; //用count计数,等会再转为string } } return tmp2; } } #endif main.cpp #include <iostream> #include "BigNum.h" #include "program.h" using namespace std; int main() { Program loader; loader.run(); } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |