C++ -- 高精度模板

百度百科

我对百度百科的内容加上了注释和一个题目的AC代码帮助大家快速入手

模板

#include <iostream>
#include<vector>
using namespace std;
//定义结构体 
struct Wint:vector<int>{//继承 vector ---用标准库vector做基类,完美解决位数问题,同时更易于实现
	Wint(int n=0 ){     //构造函数当 结构体没有输入时提供默认值 
		push_back(n);   //加入n 
		check();        
	}
	Wint& check()       //在各类运算中经常用到的进位小函数,不妨内置
    {
        while(!empty()&&!back())pop_back();//去除最高位可能存在的0  当其不是0并且返回容器中的最后一个地址 如何不存在会返回null 
        if(empty())return *this;           //如果是空则直接返回 
    	for(int i =1 ;i<size();++i){       //处理进位 
    		(*this)[i]+=(*this)[i-1]/10;
            (*this)[i-1]%=10;
		} 
		//处理最高位
		while(back()>=10)
        {
            push_back(back()/10);
            (*this)[size()-2]%=10;  //因为加了一位所以这里变成了 size()-2 
        } 
        return *this; 
    }
};
//输入输出
//输入输出  预先知识 operation是运算重载后面加上重载的运算符 istream表示输入流 outsream 
istream& operator>>(istream &is,Wint &n)
{
    string s;      //定义一个字符串 
    is>>s;		   // 
    n.clear();     //函数进位 
    for(int i=s.size()-1; i>=0; --i)n.push_back(s[i]-'0');
    return is;
}
ostream& operator<<(ostream &os,const Wint &n)
{
    if(n.empty())os<<0;
    for(int i=n.size()-1; i>=0; --i)os<<n[i];
    return os;
} 

//比较,只需要写两个,其他的直接代入即可
//常量引用当参数,避免拷贝更高效   
//先比较大小人然后挨个比价 
bool operator!=(const Wint &a,const Wint &b)
{
    if(a.size()!=b.size())return 1;
    for(int i=a.size()-1; i>=0; --i)
        if(a[i]!=b[i])return 1;
    return 0;
}
bool operator==(const Wint &a,const Wint &b)
{
    return !(a!=b);
}
//同理 先比较大小然后比较每个字母的优先级 因为我们的内容是倒序储存所以实在a.size()-1开始 
bool operator<(const Wint &a,const Wint &b)
{
    if(a.size()!=b.size())return a.size()<b.size();
    for(int i=a.size()-1; i>=0; --i)
        if(a[i]!=b[i])return a[i]<b[i];
    return 0;
}
//下面用逻辑解决了 真的nb! 
bool operator>(const Wint &a,const Wint &b)
{
    return b<a;
}
bool operator<=(const Wint &a,const Wint &b)
{
    return !(a>b);
}
bool operator>=(const Wint &a,const Wint &b)
{
    return !(a<b);
}
//加法,先实现+=,这样更简洁高效
//加法 就是每个部分相加 然后check()一下 
Wint& operator+=(Wint &a,const Wint &b)
{
    if(a.size()<b.size())a.resize(b.size());
    for(int i=0; i!=b.size(); ++i)a[i]+=b[i];
    return a.check();
}
Wint operator+(Wint a,const Wint &b)
{
    return a+=b;
}
//减法,返回差的绝对值,由于后面有交换,故参数不用引用
//由于返回的是绝对值 其实还可以稍微改一下。 就是加上前面的判断大小 
Wint& operator-=(Wint &a,Wint b)
{
    if(a<b)swap(a,b);
    for(int i=0; i!=b.size(); a[i]-=b[i],++i)
        if(a[i]<b[i])//需要借位
        {
            int j=i+1;
            while(!a[j])++j;
            while(j>i)
            {
                --a[j];
                a[--j]+=10;
            }
        }
    return a.check();
}
Wint operator-(Wint a,const Wint &b)
{
    return a-=b;
}
//乘法不能先实现*=,原因自己想

//我个人认为是因为 加和减只会对自己那一位上的数字产生影响,但是*会对所有的产生影响。求指点! 
//基础乘法的理论 
Wint operator*(const Wint &a,const Wint &b)
{
    Wint n;
    n.assign(a.size()+b.size()-1,0);
    for(int i=0; i!=a.size(); ++i)
        for(int j=0; j!=b.size(); ++j)
            n[i+j]+=a[i]*b[j];
    return n.check();
}
Wint& operator*=(Wint &a,const Wint &b)
{
    return a=a*b;
}
//除法和取模先实现一个带余除法函数
Wint divmod(Wint &a,const Wint &b)
{
    Wint ans;
    for(int t=a.size()-b.size(); a>=b; --t)
    {
        Wint d;
        d.assign(t+1,0);  //初始化全部为 0 
        d.back()=1;		  //最后一位改成 1 
        Wint c=b*d;		  //其实就是c赋予b的值 
        while(a>=c)
        {
            a-=c;
            ans+=d;
        }
    }
    return ans;
}
Wint operator/(Wint a,const Wint &b)
{
    return divmod(a,b);
}
Wint& operator/=(Wint &a,const Wint &b)
{
    return a=a/b;
}
Wint& operator%=(Wint &a,const Wint &b)
{
    divmod(a,b);
    return a;
}
Wint operator%(Wint a,const Wint &b)
{
    return a%=b;
}
//顺手实现一个快速幂,可以看到和普通快速幂几乎无异
Wint pow(const Wint &n,const Wint &k)
{
    if(k.empty())return 1;
    if(k==2)return n*n;
    if(k.back()%2)return n*pow(n,k-1);
    return pow(pow(n,k/2),2);
}


int main(){
	
	
	return 0;
}

一个简单的模板题

题目连接--阶乘之和

AC代码直接书写main函数中的内容

    int n;
    Wint ans=0,num=1;
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        num=num*i;
        ans=ans+num;
    }
    cout<<ans<<endl;

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值