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/p/2648553.html