对上一版本的改进地方在于,用减法代替除法时,直接将减数补0对齐被减数(参考北大那本书上提到的算法,但依旧没过了。。)
Code:
//两个大整数相除和取余。有改进,但依旧过不了
#include<cstdio>
#include<iostream>
#include<cstring>
#include<string>
#define MAXN 200
using namespace std;
struct bign
{
int len,s[MAXN];
bign(){ memset(s,0,sizeof(s)); len=1;}
bign(const bign& c)
{
*this=c;
}
bign(const char* num){ *this=num; }
void clean()
{//去除前导0
while(len>1 && !s[len-1]) len--;
}
string str() const
{
string res="";
for(int i=0;i<len;++i) res=(char)(s[i]+'0')+res;
return res;
}
bign operator=(const bign &b)
{
len=b.len;
for(int i=0;i<MAXN;++i)
s[i]=b.s[i];
}
bign operator=(const char *num)
{
len=strlen(num);
for(int i=0;i<len;++i) s[i]=num[len-1-i]-'0';
return *this;
}
bign operator+(const bign &b) const
{
bign c;
c.len=0;
for(int i=0,g=0;i<max(len,b.len)||g;++i)
{
int x=g;
if(i<len) x+=s[i];
if(i<b.len) x+=b.s[i];
c.s[c.len++]=x%10;
g=x/10;
}
return c;
}
bign operator-(const bign& b) const
{
bign c;
c.len=0;
for(int i=0,g=0;i<len;++i)
{
int x=s[i]-g;
if(i<b.len) x=x-b.s[i];
if(x<0)
{
x=x+10;
g=1;
}
else g=0;
c.s[c.len++]=x;
}//for
c.clean();//去除前导0
return c;
}
bign operator/(const bign& b) const
{
bign c=*this;
bign s;//商
for(int i=len-b.len;i>=0;--i)
{
bign d=b.scale(i);
int n=0;
while(c>=d)
{
c=c-d;
n=n+1;
}
s.s[i]=n;
}//for
return s;
}
bign scale(int n) const
{//把该数扩大n倍,即在该数尾部添n个0
string s=(*this).str();
string ts(n,'0');
s=s+ts;
return bign(s.c_str());
}
bign operator%(const bign& b) const
{
bign c=*this;
for(int i=len-b.len;i>=0;--i)
{
bign d=b.scale(i);
while(c>=d)
{
c=c-d;
}
}//for
return c;
}
bool operator<(bign& b)
{//该函数首先调用clean函数去除前导0,所以可能改变bign变量
clean();
b.clean();
if(len!=b.len) return len<b.len;
for(int i=len-1;i>=0;--i)
if(s[i]!=b.s[i]) return s[i]<b.s[i];
return false;
}
bool operator>=(bign &b)
{
return !(*this<b);
}
};
istream& operator>>(istream& in, bign& x)
{
string s;
cin>>s;
x=s.c_str();
return in;
}
ostream& operator<<(ostream& out, const bign& x)
{
out<<x.str();
return out;
}
int main()
{
bign a,b,s,m;
char c;
while(cin>>a>>c>>b)
{
if(c=='/') cout<<a/b<<endl;
else cout<<a%b<<endl;
}
return 0;
}