HugeInt及FACT实现

//最初实现的版本比lisp写的fact要慢很多(1/5的效率),多次优化后终于比lisp快了。还能怎么提高效率?
//
HugeInt.h: interface for the HugeInt class.
#ifndef HUGEINT_H #define HUGEINT_H #include<iostream> #include<vector> class HugeInt { enum {computebound=1000000000,computewidth=9}; typedef unsigned int eletype; public: HugeInt(); HugeInt(int); HugeInt(int,int); bool operator==(const HugeInt &)const; HugeInt operator+(const HugeInt &)const; HugeInt operator*(const HugeInt &)const; friend std::ostream & operator<<(std::ostream &,const HugeInt &); private: std::vector<eletype> m_Buffer; HugeInt domul(eletype ,int)const; }; std::ostream & operator<<(std::ostream &,const HugeInt &); #endif
#include "HugeInt.h"
#include<iomanip>
#include<algorithm>
HugeInt::HugeInt()
{

}

HugeInt::HugeInt(int Value)
{
    eletype x(Value);
    eletype y=x/computebound;
    if(y)
    {
            m_Buffer.push_back(x%computebound);
            m_Buffer.push_back(y);
       }
    else
    {
            m_Buffer.push_back(x);
    }
}
HugeInt::HugeInt(int size,int value):m_Buffer(size,value)
{

}

bool HugeInt::operator==(const HugeInt &Value)const
{
    if(m_Buffer.size()!=Value.m_Buffer.size())return false;
    return std::equal(m_Buffer.begin(),m_Buffer.end(),Value.m_Buffer.begin());

}

HugeInt HugeInt::operator+(const HugeInt &Rv)const
{
    const HugeInt &Da=(m_Buffer.size()>Rv.m_Buffer.size())?*this:Rv;
    const HugeInt &Xiao=(this==&Da)?Rv:*this;

    HugeInt Ret(Da.m_Buffer.size()+1,0);

    eletype jw=0;
    eletype *pos=&Ret.m_Buffer[0];
    const eletype *pos1=pos+Xiao.m_Buffer.size();
    const eletype *pos2=pos+Da.m_Buffer.size();
    const eletype *posda=&Da.m_Buffer[0];
    const eletype *posxiao=&Xiao.m_Buffer[0];

    for(;pos<pos1;++pos,++posda,++posxiao)
    {
        *pos=*posda + *posxiao + jw;

        jw=0;
        if(*pos>computebound)
        {
            ++jw;
            *pos-=computebound;
        }
    }

    for(;pos<pos2;++pos,++posda)
    {
        *pos=*posda+jw;

        jw=0;
        if(*pos>computebound)
        {
            ++jw;
            *pos-=computebound;
        }
        if(jw==0)
        {
            ++pos;
            ++posda;
            std::copy(posda,posda+(pos2-pos),pos);
            pos=const_cast<eletype *>(pos2);
            break;
        }

    }

    if(!(jw==0))
    {
        *pos=jw;
        ++pos;
    }
    Ret.m_Buffer.resize(pos-&Ret.m_Buffer[0]);
    return Ret;
}

HugeInt HugeInt::domul( eletype x,int y)const
{
    if(x==0)return HugeInt();
    if(x==1)
    {
        HugeInt Ret(m_Buffer.size()+y,0);        
        std::copy(m_Buffer.begin(),m_Buffer.end(),Ret.m_Buffer.begin()+y);
        return Ret;
    }

    HugeInt Ret(m_Buffer.size()+1+y,0);
    eletype jw=0;
    eletype *pos=&Ret.m_Buffer[0]+y;
    const eletype *pos1=pos+m_Buffer.size();
    const eletype *pos2=&m_Buffer[0];

    unsigned long long tmp;
    for(;pos<pos1;++pos,++pos2)
    {
        tmp=(*pos2)*(unsigned long long)x+jw;

        jw=tmp/computebound;
        *pos=tmp-jw*computebound;
    }
    if(!(jw==0))
    {
        *pos=jw;
        ++pos;
    }
    Ret.m_Buffer.resize(pos-&Ret.m_Buffer[0]);
    return Ret;
}
HugeInt HugeInt::operator*(const HugeInt &Rv)const
{
    HugeInt Ret;

    for (int i=0;i<Rv.m_Buffer.size();++i)
    {
        if(Rv.m_Buffer[i]==0)continue;
        Ret=Ret+domul(Rv.m_Buffer[i],i);
    }

    return Ret;
}
std::ostream & operator<<(std::ostream &out,const HugeInt &Value)
{
    int i=Value.m_Buffer.size()-1;
    out<<Value.m_Buffer[i];
    --i;
    for(;i>=0;--i)
    {
        out<<std::setfill('0')<<std::setw(HugeInt::computewidth)<<Value.m_Buffer[i];
    }
    return out;
}
#include <iostream>
#include "HugeInt.h"


HugeInt fact(int x)
{
    HugeInt ret=1;
    if(x<2)return ret;

    for(int i=2;i<=x;++i)
    {
        ret=ret*i;
    }
    return ret;
}


int main()
{
        while(1)
    {
        int x;
        HugeInt tmp;
        std::cin>>x;
        {
            tmp=fact(x);
        }
        std::cout<<tmp<<std::endl;
        break;
    }
    return 0;
}

  

转载于:https://www.cnblogs.com/vsuu/archive/2012/08/21/2648553.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
实现形如cout<<hex<<huge_int这样的输出,可以通过重载operator<<函数来实现。具体来说,需要在巨型整数类中定义一个友元函数operator<<,并在其中使用流插入运算符<<来实现输出操作。下面是一个示例代码: ```cpp #include <iostream> #include <vector> #include <algorithm> #include <iomanip> using namespace std; class HugeInt { public: HugeInt() {} HugeInt(int num) { while (num > 0) { digits_.push_back(num % kBase); num /= kBase; } } friend ostream& operator<<(ostream& os, const HugeInt& num) { if (num.digits_.empty()) { os << "0"; return os; } if (os.flags() & ios::hex) { // 判断是否需要输出为16进制 os << hex << num.digits_.back(); for (int i = num.digits_.size() - 2; i >= 0; --i) { os << setfill('0') << setw(kDigitWidth) << hex << num.digits_[i]; } } else { os << num.digits_.back(); for (int i = num.digits_.size() - 2; i >= 0; --i) { os << setfill('0') << setw(kDigitWidth) << num.digits_[i]; } } return os; } private: static constexpr int kBase = 10000; static constexpr int kDigitWidth = 4; vector<int> digits_; }; int main() { HugeInt a(1234567890); cout << a << endl; // 输出:1234567890 cout << hex << a << endl; // 输出:499602d2 return 0; } ``` 在上面的代码中,我们重载了operator<<函数,并判断是否需要输出为16进制。如果需要输出为16进制,我们就使用hex格式化输出,否则就直接输出。另外,我们使用了iomanip库中的setfill和setw函数来控制输出格式,使之更加美观。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值