大整数问题之终结篇,除法运算最为复杂
主要操作:
①字符数组转置,头部存储个位,这样可使操作更为方便一些
②头置零的处理,但需要保证单个零的完整输出
③字符和整数,切勿混淆‘0’和0
④估算最后结果大致为多少位,定义MAXN
注意:①处有补充!初始化时要注意一下
//未通过
#include <iostream> #include <string> int const MAXN=1000; using namespace std; class BigNumber { public: BigNumber(); BigNumber(int num); BigNumber(const char *num); BigNumber operator=(const char *num); BigNumber operator=(int num); BigNumber operator+(const BigNumber &c)const; BigNumber operator-(const BigNumber &c)const; BigNumber operator*(const BigNumber &c)const; BigNumber operator/(const BigNumber &c)const; BigNumber operator%(const BigNumber &c)const; BigNumber operator+=(const BigNumber &c) { *this=*this+c; return *this; } BigNumber operator-=(const BigNumber &c) { *this=*this-c; return *this; } BigNumber operator*=(const BigNumber &c) { *this=*this*c; return *this; } BigNumber operator/=(const BigNumber &c) { *this=*this/c; return *this; } BigNumber operator%=(const BigNumber &c) { *this=*this%c; return *this; } bool operator<(const BigNumber &c)const; bool operator>(const BigNumber &c)const { return c<*this; } bool operator<=(const BigNumber &c)const { return !(*this>c); } bool operator>=(const BigNumber &c)const { return !(*this<c); } bool operator==(const BigNumber &c)const { return (*this<=c)&&(*this>=c); } bool operator!=(const BigNumber &c)const { return !(*this<c)&&!(*this>c); } void cleanLeadZero(); //void divisionTen(int n); //void mutiplyTen(int n); string str()const; BigNumber getSub(int n)const; friend istream & operator>>(istream &in,BigNumber &c); friend ostream & operator<<(ostream &in,BigNumber &c); private: int s[MAXN]; int len; }; BigNumber::BigNumber() { memset(s,0,sizeof(s)); len=1;//这样设置使初始化的值为零 } BigNumber::BigNumber(const char *num) { *this=num; } BigNumber::BigNumber(int num) { *this=num; } string BigNumber::str()const { string r=""; for(int i=0;i<len;i++) r=(char)(s[i]+'0')+r; if(r=="") r="0"; return r; } BigNumber BigNumber::operator=(const char *num) { len=strlen(num);//①前面加一句memset(num,0,sizeof(num));效果会很好 for(int i=0;i<len;i++) s[i]=num[len-1-i]-'0'; return *this; } BigNumber BigNumber::operator=(int num) { char r[MAXN]; sprintf(r,"%d",num); *this=r; return *this; } void BigNumber::cleanLeadZero() { while(len>1 && !s[len-1])//此处注意len>1,保证单个0的输出 len--; } BigNumber BigNumber::operator+(const BigNumber &c)const { BigNumber r; r.len=0; int up=0; int maxlen=len>c.len?len:c.len; for(int i=0;up || i<maxlen;i++) { int temp=up; if(i<len) temp+=s[i];//###,这里需要判断的是i<len,而不是s[i]是否为零 if(i<c.len) temp+=c.s[i]; r.s[r.len++]=temp%10; up=temp/10; } r.cleanLeadZero(); return r; } //a-b时要确保,a>b BigNumber BigNumber::operator-(const BigNumber &c)const { BigNumber r; r.len=0; int down=0; for(int i=0;i<len;i++) { int temp=s[i]-down; if(i<c.len) temp-=c.s[i];//这里是-; if(temp>=0) down=0; else { down=1; temp+=10; } r.s[r.len++]=temp; } r.cleanLeadZero(); return r; } BigNumber BigNumber::operator*(const BigNumber &c)const//大整数问题的另外一种操作,不需要中间变量 { BigNumber r; r.len=len+c.len; for(int i=0;i<len;i++) { for(int j=0;j<c.len;j++) { r.s[i+j]+=s[i]*c.s[j];//###,+= } } for(int i=0;i<r.len-1;i++) { r.s[i+1]+=r.s[i]/10; r.s[i]%=10; } r.cleanLeadZero(); return r; } BigNumber BigNumber::getSub(int n)const //###“BigNumber::getSub”: 不能将“this”指针从“const BigNumber”转换为“BigNumber &” //出现这个错误后,将函数设置成const即可 { BigNumber r; r.len=0; for(int i=0;i<n;i++) { r.s[r.len++]=s[len-n+i]; } return r; } BigNumber BigNumber::operator/(const BigNumber &c)const { BigNumber r; r.len=0; BigNumber temp=getSub(c.len-1); for(int i=len-c.len;i>=0;i--) { temp=temp*10+s[i]; if(temp<c) r.s[r.len++]=0; else { int j; for(j=1;j<=10;j++)//这里最大值可以取到10 if(c*j>temp)//c要放到*的前面,这样才可以调用operator*函数 break; r.s[r.len++]=j-1; temp=temp-(c*(j-1)); } } for(int i=0;i<r.len/2;i++) { char mid=r.s[i]; r.s[i]=r.s[r.len-1-i]; r.s[r.len-1-i]=mid; } r.cleanLeadZero(); return r; } BigNumber BigNumber::operator%(const BigNumber &c)const { BigNumber r; r=*this/c; r=*this-r*c; return r; } bool BigNumber::operator<(const BigNumber &c)const { if(len!=c.len) return len<c.len; else { for(int i=len-1;i>=0;i--)//一失足成千古恨,i-- if(s[i]!=c.s[i]) return s[i]<c.s[i]; } return false; } istream & operator>>(istream &in,BigNumber &c) { string str; in>>str; c=str.c_str(); return in; } ostream & operator<<(ostream &out,BigNumber &c) { out<<c.str(); return out; } char a[1000]; char b[100]; char op; int main() { while(scanf("%s %c %s",a,&op,b)==3) { BigNumber f1(a); BigNumber f2(b); if(op=='/') cout<<f1/f2<<endl; else if(op=='%') cout<<f1%f2<<endl; } return 0; }
第二次做:Runtime error
#include <iostream> #include <cstdio> #include <cstring> using namespace std; const int nMax=100; class BigNumber { private: int f[nMax]; int len; public: BigNumber(){len=1;memset(f,0,sizeof(f));} BigNumber(int a); BigNumber(char *ch); BigNumber operator=(char *ch); BigNumber operator+(const BigNumber &c)const; BigNumber operator-(const BigNumber &c)const; BigNumber operator*(const BigNumber &c)const; BigNumber operator/(const BigNumber &c)const; BigNumber operator%(const BigNumber &c)const; bool operator<(const BigNumber &c)const; bool operator>(const BigNumber &c)const{return c<*this;} bool operator==(const BigNumber &c)const{return !(*this<c) && !(c<*this);} bool operator<=(const BigNumber &c)const{return *this<c || *this==c;} friend ostream &operator<<(ostream &out,const BigNumber &c); void clearLeadZero(); BigNumber getSub(int len)const; }; BigNumber BigNumber::operator=(char *ch) { len=strlen(ch); for(int i=0;i<len;i++) f[len-1-i]=ch[i]-'0'; clearLeadZero(); return *this; } void BigNumber::clearLeadZero() { while(len>0 && !f[len-1]) len--; if(len==0) len=1,f[0]=0; } BigNumber::BigNumber(char *ch) { memset(f,0,sizeof(f)); *this=ch; } BigNumber::BigNumber(int a) { char ch[nMax]; sprintf(ch,"%d",a); memset(f,0,sizeof(f)); *this=ch; } bool BigNumber::operator<(const BigNumber &c)const { if(len!=c.len) return len<c.len; else for(int i=len-1;i>=0;i--) if(f[i]!=c.f[i]) return f[i]<c.f[i]; return 0; } BigNumber BigNumber::operator+(const BigNumber &c)const { int i,up; BigNumber z; for(i=0,up=0;i<len || i<c.len || up;i++) { int p=up+f[i]+c.f[i]; z.f[i]=p%10; up=p/10; } z.len=i; z.clearLeadZero(); return z; } //保证被减数比减数大 BigNumber BigNumber::operator-(const BigNumber &c)const { int i,down; BigNumber z; for(i=0,down=0;i<len;i++) { int p=down+f[i]-c.f[i]; if(p>=0) down=0,z.f[i]=p%10; else down=-1,z.f[i]=10+p; } z.len=i; z.clearLeadZero(); return z; } BigNumber BigNumber::operator*(const BigNumber &c)const { int i,j,up; BigNumber z; for(i=0;i<len;i++) { up=0; for(j=0;j<c.len || up;j++) { int p=up+f[i]*c.f[j]+z.f[i+j]; z.f[i+j]=p%10; up=p/10; } } z.len=i+j; z.clearLeadZero(); return z; } BigNumber BigNumber::getSub(int sub_len)const { BigNumber z; for(int i=0;i<sub_len;i++) z.f[i]=f[len-sub_len+i]; z.len=sub_len; z.clearLeadZero(); return z; } BigNumber BigNumber::operator/(const BigNumber &c)const { if(*this<c) return BigNumber(0); BigNumber z,temp; temp=getSub(c.len-1); for(int i=len-c.len;i>=0;i--) { temp=temp*10+f[i]; int k=0; while(k<10 && c*k<=temp) k++; z.f[z.len++]=k-1; } for(int i=0;i<z.len/2;i++) {int temp=z.f[i];z.f[i]=z.f[z.len-1-i];z.f[z.len-1-i]=temp;} z.clearLeadZero(); return z; } BigNumber BigNumber::operator%(const BigNumber &c)const { BigNumber z; z=(*this)-c*((*this)/c); z.clearLeadZero(); return z; } ostream &operator<<(ostream &out,const BigNumber &c) { for(int i=c.len-1;i>=0;i--) out<<c.f[i]; return out; } int main() { //freopen("f:/data.in","r",stdin); char c1[nMax],opt,c2[nMax]; while(scanf("%s %c %s",c1,&opt,c2)==3) { BigNumber f1(c1); BigNumber f2(c2); if(opt=='/') cout<<f1/f2<<endl; else if(opt=='%') cout<<f1%f2<<endl; } return 0; }