高精度(大数)计算 C++
来源:互联网 发布:微赞数据库管理员密码 编辑:程序博客网 时间:2024/05/23 16:54
今天重新写了一下C++的大数计算。 这次使用的标准库中的string重载运算符实现的。 跑OJ上的题,7ms 71KB,而以前用char数组直接写,6ms 48kb,可以看出,stl中的模板的效率已经很高了,在时间上基本差不多,主要是在空间上有一些浪费,但是考虑到其简单性和健壮性,STL是个非常好的选择。
这是代码:
//fuxiaotong 1067
#include <iostream>#include <string>using namespace std;class BigInt{friend istream & operator>>(istream &,BigInt &);friend ostream & operator<<(ostream &,const BigInt &);public:BigInt operator* (const BigInt &) const;BigInt operator/ (const BigInt &) const;BigInt operator% (const BigInt &) const;bool isZero();private:string str;};istream & operator>>(istream & myin,BigInt & x){myin>>x.str;return myin;}ostream & operator<<(ostream & myout, const BigInt & x){myout<<x.str;return myout;}BigInt BigInt::operator*(const BigInt & x) const{BigInt y;int lena,lenb,lenc,i,j,k,m;lena = str.length();lenb = x.str.length();lenc = lena+lenb;y.str.assign(lenc,'0');for(i = lenb-1;i>=0;--i){ //bfor(j = lena-1;j>=0;--j){ //ak = lenc-lenb+i-lena+1+j;//lenc-1 - ((lenb-1-i) + (lena-1-j));m = (str[j]-'0') * (x.str[i]-'0') + y.str[k] - '0';y.str[k] = m % 10 + '0';y.str[k-1] += m / 10;}}while(y.str.size()>1 && y.str[0]=='0') y.str.erase(y.str.begin());return y;}BigInt BigInt::operator%(const BigInt & x) const{int lena,lenb;int i,k;BigInt t;t.str = str;lena = str.length();lenb = x.str.length();if(lena>=lenb){i=0;while(i<=lena-lenb){while(t.str.substr(i,lenb)>=x.str ){for(k=lenb-1;k>=0;--k){if(t.str[i+k]<x.str[k]) { //借位--t.str[i+k-1];t.str[i+k] += 10;}t.str[i+k] = t.str[i+k] - x.str[k] + '0';}}if(i!=lena-lenb){ //如果剩最后lenb位,不必移动i,避免t出现借位后超过9,二来避免超过a的最低位t.str[i+1] += (t.str[i]-'0') * 10; //避免判断不同位情况 直接把高位值降位t.str[i] = '0'; //高位清零}++i;}}while(t.str[0]=='0' && t.str.size()>1) t.str.erase(t.str.begin());return t;}BigInt BigInt::operator/(const BigInt & x) const{int lena,lenb,lenc;int i,k;BigInt t,y;lena = str.length();lenb = x.str.length();if(lenb>lena) lenc = 1;else lenc = lena-lenb+1;t.str = str;y.str.assign(lenc,'0');if(lenb<=lena){i=0;while(i<=lena-lenb){while(t.str.substr(i,lenb)>=x.str){for(k=lenb-1;k>=0;--k){if(t.str[i+k]<x.str[k]){--t.str[i+k-1];t.str[i+k] += 10;}t.str[i+k] = t.str[i+k] - x.str[k] + '0';}++y.str[i];}if(i!=lena-lenb) t.str[i+1] += (t.str[i]-'0') * 10;++i;}if(y.str.size()>1 && y.str[0]=='0') y.str.erase(y.str.begin());}return y;}bool BigInt::isZero(){if(str.length()==1 && str[0]=='0') return true;else return false;}BigInt gcd(BigInt a,BigInt b){if(b.isZero()) return a;else return gcd(b,a%b);}int main(){BigInt a,b;while(true){ cin>>a>>b;if(a.isZero() && b.isZero()) break; // a,b不同时为零,可以其中一个为0cout<<a*b/gcd(a,b)<<endl;}return 0;}
用到了sting的operator=,[],assign,length,erase,size,begin,substr。
几点注意:
1. string的[]符号基本和CHAR*差不多,可以修改值,取值,和string.h cstring似乎有不同
2.stl中的位置确定,不能直接s.erase(0),要用begin函数确定
3. a -= c+d 是 a = a-(c+d),不是a = a - c + d。
《大师》第三章结束了,对消息基本了解清楚了,第四章开始讲了最古老的GDI函数, windows自带的pen 和 brush。想起了小学的时候在DOS系统下的乌龟画画(输入指定,一个箭头根据你的指令移动画图)。基本分3步走:
1. 建立(初始化)pen = GetStockObject() 或者 brush = CreateHatchBrush(RGB());
2.选择 SelectObject(hdc,brush);
3.使用
4.删除 DeleteObject(brush);
大概这些老古董会派上用场吧
- 高精度(大数)计算 C++
- 大数,高精度计算---大数加法
- 大数,高精度计算---大数减法
- 大数,高精度计算---大数乘法
- 大数,高精度计算---大数除法
- 大数,高精度计算---大数阶乘
- 大数,高精度计算---百位大数
- 大数,高精度计算---大数阶乘
- 大数,高精度计算---大数减法
- 高精度计算 大数减法
- 高精度计算 大数乘法
- 大数,高精度计算---高精度幂次
- 8、大数,高精度计算---高精度幂次
- 4、 大数,高精度计算---大数加法
- 5、大数,高精度计算---大数减法
- 6、大数,高精度计算---大数乘法
- 7、大数,高精度计算---大数除法
- 9、 大数,高精度计算---大数阶乘
- linux gcc make命令使用规则
- 远程登录工具 FAQ
- pro*c/c++编译错误 ” error: sqlca.h: No such file or directory “ 的解决办法
- diff & patch 制作及打补丁
- 使用PHP导入Excel和导出数据为Excel文件
- 高精度(大数)计算 C++
- jquery写的左右滚动插件
- 升级Xcode4.5之后,bash中SVN命令未找到
- HGE与MFC结合-视频播放
- uva11552
- Troubleshooting MySQL
- SVM分类算法
- debian6 添加nfs服务
- nmon免费性能分析工具