10494 - If We Were a Child Again大总结


大整数问题之终结篇,除法运算最为复杂

主要操作:

①字符数组转置,头部存储个位,这样可使操作更为方便一些

②头置零的处理,但需要保证单个零的完整输出

③字符和整数,切勿混淆‘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;
}


你可能感兴趣的:(10494 - If We Were a Child Again大总结)