偶然间发现去年写的课程设计作业,写的还不错,涉及的知识面还挺多的,现在都有些记不得了,有时间得好好看看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!