高精度(大数)计算 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);


        大概这些老古董会派上用场吧


原创粉丝点击