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; }