您的位置:首页 > 编程语言 > C语言/C++

C++课程设计之大整数类

2013-12-16 09:35 162 查看
偶然间发现去年写的课程设计作业,写的还不错,涉及的知识面还挺多的,现在都有些记不得了,有时间得好好看看c++了。

题目: 设计并实现大整数类,并测试其加减乘除运算(至少有一个数是20位以上的整数)。利用它计算并显示30!。(要求:必须实现拷贝构造函数、四则运算重载、友元函数、插入和提取运算符重载)



问题分析:

要想实现真正的大整数类,即其位数不确定且可以无限大,那么选择容器是最佳的,用数组的话必须确定其大小,那么这个所谓的大整数的位数就有了上限,所以这里我选择用vector,并使用string类对其进行输入输出操作,代码如下。实现了拷贝构造函数、四则运算重载、友元函数、插入和提取运算符重载。四则运算对于负数也是适用的,除法只考虑求商。

代码实现:(运行环境为Microsoft Visual Studio 2010)

#include<iostream>
#include<vector>
#include<string>
#include<cstring>
using namespace std;
class BigInt
{
public:
	BigInt();
	BigInt(long int s);
	BigInt(string str);
	BigInt(BigInt& a);
	friend BigInt operator+(BigInt a,BigInt b);
	friend BigInt operator-(BigInt a,BigInt b);
	friend BigInt operator*(BigInt a,BigInt b);
	friend BigInt operator/(BigInt a,BigInt b);//除法算法不太好
	friend ostream& operator<<(ostream& out,BigInt& a);
	friend istream& operator>>(istream& in,BigInt& a);
	BigInt operator=(BigInt a);
	friend int SizeJudge(BigInt a,BigInt b);
	vector<int> vec;
	int negative;//0为正,1为负
};
BigInt::BigInt()
{
	vec.push_back(0);
	negative = 0;
}
BigInt::BigInt(long int s)
{
	if(s<0)
	{
		negative = 1;
		s = -s;
	}
	else
		negative = 0;
	int i;
	while(s>9)
	{
		i = s%10;
		vec.push_back(i);
		s /=10;
	}
	vec.push_back(s);
}
BigInt::BigInt(string str)
{
	if(str[0] == '-')
	{
		negative = 1;
		str = str.substr(1,str.size()-1);
	}
	else
		negative = 0;
	for(int i=str.size()-1;i>=0;i--)
	{
		vec.push_back(str[i]-'0');
	}
}
BigInt::BigInt(BigInt& a)
{
	vec = a.vec;
	negative = a.negative;
}
BigInt BigInt::operator=(BigInt a)
{
	vec = a.vec;
	negative = a.negative;
	return *this;
}
ostream& operator<<(ostream& out,BigInt& a)
{
	string str="";
	int judge = 0;
	if((a.vec[a.vec.size()-1]+'0') == '-')
		judge = 1;
	if((a.negative == 1)&&judge == 0)
	{
		str += '-';
	}
	for(int i=a.vec.size()-1;i>=0;i--)
	{
		str += (a.vec[i]+'0');
	}
	out<<str;
	return out;
}
istream& operator>>(istream& in,BigInt& a)
{
	string str="";
	in>>str;
	a.vec.clear();
	for(int i=str.size()-1;i>=0;i--)
	{
		a.vec.push_back(str[i]-'0');
	}
	return in;
}
BigInt operator+(BigInt a,BigInt b)
{
	int negative_judge = 0;
	if(a.negative == 1&&b.negative == 1)//全负
	{
		negative_judge = 1;
	}
	if(a.negative == 0&&b.negative == 0)//全正
	{
		negative_judge = 0;
	}
	if(a.negative == 0&&b.negative == 1)//a正b负
	{
		b.negative = 0;
		return (a-b);
	}
	if(a.negative == 1&&b.negative == 0)//a负b正
	{
		a.negative = 0;
		return (b-a);
	}
	BigInt c,tmp;
	int alen,blen,min,max,i;
	alen = a.vec.size();
	blen = b.vec.size();
	if(alen>blen)
	{
		c.vec = a.vec;
		tmp.vec = b.vec;
		min = blen;
		max = alen;
	}
	else
	{
		c.vec = b.vec;
		tmp.vec = a.vec;
		min = alen;
		max = blen;
	}
	for(i=0;i<min-1;i++)//min=max?
	{
		c.vec[i] += tmp.vec[i];
		if(c.vec[i]>9)
		{
			c.vec[i] -= 10;
			c.vec[i+1] += 1;
		}
	}
	c.vec[i] +=tmp.vec[i];
	if(c.vec[i]>9)
	{
		c.vec[i] -=10;
		if(min == max)
			c.vec.push_back(1);
		else
			c.vec[i+1] +=1;
	}
	for(i=min;i<max-1;i++)
	{
		if(c.vec[i]>9)
		{
			c.vec[i] -=10;
			c.vec[i+1] +=1;
		}
	}
	if(c.vec[max-1]>9)
	{
		c.vec[max-1] -=10;
		c.vec.push_back(1);
	}
	i=c.vec.size()-1;//去掉前面的0
	while(c.vec[i] == 0)
	{
		c.vec.pop_back();
		i--;
	}
	if(negative_judge == 1)
	{
		string str = "-";
		c.vec.push_back(str[0]-'0');
	}
	return c;
}
BigInt operator-(BigInt a,BigInt b)
{
	int negative_judge = 0;
	if(a.negative == 1&&b.negative == 1)//全负
	{
		a.negative = 0;
		b.negative = 0;
		return (b-a);
	}
	if(a.negative == 0&&b.negative == 0)//全正
	{
		negative_judge = 0;
	}
	if(a.negative == 0&&b.negative == 1)//a正b负
	{
		b.negative = 0;
		return (a+b);
	}
	if(a.negative == 1&&b.negative == 0)//a负b正
	{
		b.negative =1;
		return (a+b);
	}
	BigInt c,tmp;
	int alen,blen,min,max,i,judge=0;
	alen = a.vec.size();
	blen = b.vec.size();
	//大值赋给c,小值赋给tmp
	if(alen>blen)
	{
		c.vec = a.vec;
		tmp.vec = b.vec;
		min = blen;
		max = alen;
		judge = 1;
	}
	else if(alen == blen)
	{
		for(i=alen-1;i>=0;i--)
		{
			if(a.vec[i]>b.vec[i])
			{
				c.vec = a.vec;
				tmp.vec = b.vec;
				min = blen;
				max = alen;
				judge = 1;
				break;
			}
			else if(a.vec[i]<b.vec[i])
			{
				c.vec = b.vec;
				tmp.vec = a.vec;
				min = alen;
				max = blen;
				judge = 2;
				break;
			}
		}
		if(i==-1)
			return (BigInt)0;
	}
	else
	{
		c.vec = b.vec;
		tmp.vec = a.vec;
		min = alen;
		max = blen;
		judge = 2;
	}
	for(i=0;i<min;i++)//min=max?c>tmp
	{
		c.vec[i] -= tmp.vec[i];
		if(c.vec[i]<0)
		{
			c.vec[i] += 10;
			c.vec[i+1] -= 1;
		}
	}
	if(min<max)
		for(i=min;i<max;i++)
		{
			if(c.vec[i]<0)
			{
				c.vec[i] +=10;
				c.vec[i+1] -=1;
			}
		}
		if(judge == 2)
		{
			string str="-";
			c.vec.push_back(str[0]-'0');
		}
		i=c.vec.size()-1;//去掉前面的0
		while(c.vec[i] == 0)
		{
			c.vec.pop_back();
			i--;
		}
		return c;
}
BigInt operator*(BigInt a,BigInt b)
{
	BigInt c;
	int alen,blen,i,j,max,tmp;
	alen = a.vec.size();
	blen = b.vec.size();
	max = alen+blen;
	c.vec.clear();
	for(i=0;i<max;i++)
	{
		c.vec.push_back(0);
	}
	for(i=0;i<alen;i++)
	{
		for(j=0;j<blen;j++)
		{
			tmp = c.vec[i+j]+a.vec[i]*b.vec[j];
			if(tmp>9)
			{
				if(i+j+1<max)
				{
					c.vec[i+j+1] += tmp/10;
					tmp %= 10;
				}
				else
				{
					c.vec.push_back(tmp/10);
					tmp %= 10;
				}
			}
			c.vec[i+j] = tmp;
		}
	}
	i=c.vec.size()-1;//去掉前面的0
	while(c.vec[i] == 0)
	{
		c.vec.pop_back();
		i--;
	}
	if((a.negative == 0&&b.negative == 1)||(a.negative ==  
1&&b.negative == 0))//a正b负//a负b正
	{
		string str="-";
		c.vec.push_back(str[0]-'0');
		c.negative = 1;
	}
	else
	{
		c.negative = 0;
	}
	return c;
}
BigInt operator/(BigInt a,BigInt b)
{
	if(SizeJudge(a,b) == -1)
	{
		return (BigInt)0;
	}
	else if(SizeJudge(a,b) == 0)
	{
		return (BigInt)1;
	}
	BigInt tmp;
	int alen,blen,i;
	alen = a.vec.size();
	blen = b.vec.size();
	if(blen == 1&&b.vec[0] == 0)
	{
		BigInt err("error");
		return err;
	}
	i = alen-blen;
	int j = 1;
	while(i>0)
	{
		j *=10;
		i--;
	}
	BigInt count(j);
	tmp = count*b;
	if(SizeJudge(a,tmp) == 1)
	{
		while(SizeJudge(a,tmp) == 1)
		{
			count = count+1;
			tmp = b*count;
		}
	}
	else if(SizeJudge(a,tmp) == -1)
	{
		while(SizeJudge(a,tmp) == -1)
		{
			count = count-1;
			tmp = b*count;
		}
	}
	if((a.negative == 0&&b.negative == 1)||(a.negative ==  
1&&b.negative == 0))//a正b负//a负b正
	{
		string str="-";
		count.vec.push_back(str[0]-'0');
		count.negative = 1;
	}
	else
	{
		count.negative = 0;
	}
	return count;
}
int SizeJudge(BigInt a,BigInt b)
{//1代表大于,0代表等于,-1代表小于
	int alen,blen,i;
	alen = a.vec.size();
	blen = b.vec.size();
	if(alen>blen)
	{
		return 1;
	}
	else if(alen == blen)
	{
		for(i=alen-1;i>=0;i--)
		{
			if(a.vec[i]>b.vec[i])
			{
				return 1;
			}
			else if(a.vec[i]<b.vec[i])
			{
				return -1;
			}
		}
		if(i==0)
			return 0;
	}
	else
	{
		return -1;
	}
}
int main()
{
	////测试数据输入
	//BigInt a("999999999999999999999"),b("8888"),c;
	//cin>>b;
	//cout<<"the input:"<<b<<endl;
	//c = a+b;
	//cout<<a<<"+"<<b<<"="<<c<<endl;
	//cin.get();
	////测试加法
	//BigInt a("999999999999999999999"),b("8888"),c;
	//c = a+b;
	//cout<<a<<"+"<<b<<"="<<c<<endl;
	//BigInt d("-1111");
	//c = a+d;
	//cout<<a<<"+"<<d<<"="<<c<<endl;
	//c = 7777777+a;
	//cout<<"7777777"<<"+"<<a<<"="<<c<<endl;
	//BigInt s(a);//调用拷贝构造函数
	//c = s+a;
	//cout<<s<<"+"<<a<<"="<<c<<endl;
	////测试减法
	//BigInt a("999999999999999999999"),b("8888"),c;
	//c = a-b;
	//cout<<a<<"-"<<b<<"="<<c<<endl;
	//BigInt d("-1111");
	//c = a-d;
	//cout<<a<<"-"<<d<<"="<<c<<endl;
	//c = 7777777-a;
	//cout<<"7777777"<<"-"<<a<<"="<<c<<endl;
	////测试乘法
	//BigInt a("999999999999999999999"),b("8888"),c;
	//c = a*b;
	//cout<<a<<"*"<<b<<"="<<c<<endl;
	//BigInt d("-1111");
	//c = a*d;
	//cout<<a<<"*"<<d<<"="<<c<<endl;
	//c = 7777777*a;
	//cout<<"7777777"<<"*"<<a<<"="<<c<<endl;
   	///测试除法
	//BigInt a("999999999999999999999"),b("888888888888888"),c;
	//c = a/b;
	//cout<<a<<"/"<<b<<"="<<c<<endl;
	//c = b/a;
	//cout<<b<<"/"<<a<<"="<<c<<endl;
	//BigInt d("-111111111111111");
	//c = a/d;
	//cout<<a<<"/"<<d<<"="<<c<<endl;
	//c = 0/a;
	//cout<<"0"<<"/"<<a<<"="<<c<<endl;
   //计算并显示30!
	BigInt a("30"),c("1");
	int i = 30;
	while(i>0)
	{
		c = c*a;
		a = a-1;
		i--;
	}
	cout<<"30! = "<<c<<endl;
	return 0;
}


运行结果:

1.输入:




2. 加法:(包含调用拷贝构造函数)



3. 减法:




4. 乘法:




5. 除法:(求商)




6. 计算并显示30!

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: