大整数类的四则运算和逻辑运算
来源:互联网 发布:javascript 引号 转义 编辑:程序博客网 时间:2024/05/02 08:47
今天看了《算法竞赛和入门基础》中的大整数类后,我自己也试着去实现一个大整数类,并且完成了整数的四则运算和逻辑运算功能。学习到了很多东西。在此分享一下。代码是C++的。用了C++中的STL模板类vector。
大整数类的数据存储结构如下所示:
static const int BASE=100000000;
static const int WIDTH=8;
std::vector<int> s;
下面我在书里原有的基础上继续编写了乘除和减法的代码。
class BigInteger{public:
//数据存储结构 static const int BASE=100000000; static const int WIDTH=8; std::vector<int> s;
//构造函数 BigInteger(long long num=0) { *this=num; }
//long long型整数赋值方法 BigInteger operator = (long long num) { s.clear(); do{ s.push_back(num%BASE); num/=BASE; }while(num); return *this; }
//string类型赋值方法 BigInteger operator = (const std::string &str) { s.clear(); int x,len=(str.length()-1)/WIDTH+1; for(int i=0;i<len;i++) {
//从尾部开始切割 int end=str.length()-i*WIDTH; int start=std::max(0,end-WIDTH);
//用sscnaf会去除前导零,下面输出的时候要注意,不过书里代码都已经给出了,这里我代为说明一下。 sscanf(str.substr(start,end-start).c_str(),"%d",&x); s.push_back(x); } return *this; }
//加法 BigInteger operator + (const BigInteger& b) const { BigInteger c; c.s.clear(); for(int i=0,g=0;;i++) { if(g==0&&i>=s.size()&&i>=b.s.size()) break; int x=g; if(i<s.size()) x+=s[i]; if(i<b.s.size()) x+=b.s[i]; c.s.push_back(x%BASE); g=x/BASE; } return c; } BigInteger operator += (const BigInteger& b) { *this=*this+b; return *this; }
//仿照加法写的减法,需要注意的是只需在最前面加负号 BigInteger operator - (const BigInteger& b) const { BigInteger c; c.s.clear(); int MAX=std::max(s.size(),b.s.size()); for(int i=0,g=0;;i++) { if(g==0&&i>=MAX) break; int x=g; if(i<s.size()) x+=s[i]; if(i<b.s.size()) x-=b.s[i];
//!!!!!! if(i==MAX-1) c.s.push_back(x%BASE); else c.s.push_back(abs(x%BASE)); //!!!!!!
g=x/BASE; } return c; } BigInteger operator -= (const BigInteger& b) { *this=*this-b; return *this; } //自己写的,效率有点低,我把vector中的数全部转化为一个整体的string类型,再进行乘法操作,这是我最先想到的写法。 BigInteger operator * (const BigInteger& b) { std::stringstream ss; for(int i=s.size()-1;i>=0;i--) ss<<s[i]; std::string operand1=ss.str(); ss.str(""); for(int i=b.s.size()-1;i>=0;i--) ss<<b.s[i]; std::string operand2=ss.str();
//将string中的一个个数转为int型的数 std::vector<int> c,d,temp; for(int i=operand1.length()-1;i>=0;i--) c.push_back(operand1[i]-'0'); for(int i=operand2.length()-1;i>=0;i--) d.push_back(operand2[i]-'0'); int MAX=std::max(c.size(),d.size()); for(int i=0;i<MAX*2+1;i++) temp.push_back(0); for(int i=0;i<c.size();i++) for(int j=0;j<d.size();j++) temp[i+j]+=c[i]*d[j]; for(int i=0;i<2*MAX+1;i++) if(temp[i]>9) { temp[i+1]+=temp[i]/10; temp[i]%=10; } int m=2*MAX; while(temp[m]==0) m--; BigInteger another; another.s.clear(); int len=(m-1)/WIDTH+1; for(int i=0;i<len;i++) another.s.push_back(0); for(int i=0;i<len;i++) { int x=1; int k=0; int end=std::min(m+1,(i+1)*WIDTH); int start=i*WIDTH; for(int j=start;j<end;j++) { k+=x*temp[j]; x*=10; } another.s[i]=k; } return another; } BigInteger operator *= (const BigInteger& b) { *this=*this*b; return *this; }
//自己写的除法,可以实现像int型一样的效果 BigInteger operator / (const BigInteger& b) { std::string operand1,operand2,result; std::stringstream ss; for(int i=s.size()-1;i>=0;i--) ss<<s[i]; operand1=ss.str(); ss.str(""); for(int i=b.s.size()-1;i>=0;i--) ss<<b.s[i]; operand2=ss.str(); int len1,len2; len1=operand1.length(); len2=operand2.length(); if(len1<len2) //若操作数1小于操作数2,返回0 return 0; if(*this==b) //若两数相等,返回1,这里用到下面的“==”重载运算符 return 1; std::vector<int> c,d; for(int i=0;i<len1;i++) { c.push_back(operand1[i]-'0'); if(i<len2) d.push_back(operand2[i]-'0'); else d.push_back(0); } int time=len1-len2; int len=len1; int k,l=0; for(int i=0;i<=time;i++) { int ok=1; k=0; do{ if(c[l]==0) { l++; ok=0; len1--; } if(len==len1) { int j=0; while(j<len2) { if(c[i+j]>d[j]) //第一次大就表示operand1 > operand2 { ok=1; break; } else if(c[i+j]<d[j]) //第一次小就表示operand1 < operand2 { ok=0; break; } j++; } } if(ok) { for(int j=0;j<len;j++) { c[j+i]-=d[j]; if(c[j+i]<0) { c[j+i-1]--; c[j+i]+=10; } } k++; } }while(ok); len--; result+=k+'0'; } BigInteger temp; temp=result; return temp; } BigInteger operator /= (const BigInteger& b) { *this=*this/b; return *this; }
//以下的重载方法全都在上面的四则运算上编写,不再介绍 BigInteger operator % (const BigInteger& b) { BigInteger c; c=*this-(*this/b)*b; return c; } BigInteger operator %= (const BigInteger& b) { *this=*this%b; return *this; } bool operator < (const BigInteger& b) const { if(s.size()!=b.s.size()) return s.size()<b.s.size(); for(int i=s.size()-1;i>=0;i--) if(s[i]!=b.s[i]) return s[i]<b.s[i]; return false; } bool operator > (const BigInteger& b) const { return b<*this; } bool operator <= (const BigInteger& b) const { return !(b<*this); } bool operator >= (const BigInteger& b) const { return !(*this<b); } bool operator != (const BigInteger& b) const { return *this<b||*this>b; } bool operator == (const BigInteger& b) const { return !(*this<b)&&!(*this>b); } friend std::ostream& operator << (std::ostream& out,const BigInteger& x) { out<<x.s.back(); for(int i=x.s.size()-2;i>=0;i--) { char buf[20]; sprintf(buf,"%08d",x.s[i]); for(int j=0;j<strlen(buf);j++) out<<buf[j]; } return out; } friend std::istream& operator >> (std::istream& in,BigInteger& x) { std::string s; if(!(in>>s)) return in; x=s; return in; }};
全部贴出来是因为我太懒了,见谅啊。
大整数类除了这个实现,如果大家还有其他实现方法,不妨也分享一下,这里写出来只是抛砖引玉。
参考书籍:《算法竞赛和入门经典》。
2 0
- 大整数类的四则运算和逻辑运算
- 大整数的四则运算
- 大整数的四则运算
- 大整数的四则运算
- 分数类和整数类的四则运算
- 分数类和整数的四则运算
- 比较好的大整数四则运算
- [程序设计实习]大整数的四则运算
- java实现大整数的四则运算
- 大整数四则运算
- 大整数四则运算
- 大整数四则运算
- C语言-大整数四则运算
- 大整数的四则运算代码(供新手学习…
- 思路简单做起来容易出错的大整数四则运算
- C++实现高精度大整数(大数)的四则运算
- 高精度整数的四则运算
- 【11】不能使用四则运算求两个整数的和
- C#中属性PropertyInfo的使用
- 【openjudge 计算概论(A)】[基础编程练习1]
- 如果一个进程出了问题,怎么判断它是否运行?能不能重启这个进程?尝试使用守护进程来操作
- Codeforces 732C-Sanatorium
- 一串连续奇数,它们的和等于该整数的立方。找出[2,20]之间的数满足这一性质。
- 大整数类的四则运算和逻辑运算
- static+final与final区别,静态常量与常量
- 通过百度地图定位城市
- java equal 与 hashcode
- C# List<> 容器用法截图
- SSO单点登录、跨域重定向、跨域设置Cookie、京东单点登录实例分析
- df与du的区别
- 防止服务端产生的cookie被客户端的cookie替换掉
- 今天台风又来袭, 没上班, 在家写了十多篇CSDN博文,累了, 睡!