程序员都是软件开发人才啊!
之前在知乎,看到了一个问题:
这就是一个求阶乘的问题,大家刚刚开始学编程的时候应该都写过这样的程序。
一个求阶乘的问题,还能玩出什么样的花儿来?
我在回答区看到了一个非常有趣的回答,给我笑的差点喷饭,一定得分享给大家。
下面是回答正文,答主:小白白。
数学家版本:(简单利索,深藏功与名)
#includeiostream#includecmathintmain(){std::coutstd::tgamma(20+1)std::endl;}语言学家版本:
(语言学家,你懂得,恨不得把所有语法特性都派上用场)
#includeiostream#includeutilitytemplatestd::size_t...Iconstexprautofoo(std::index_sequenceI...){return((I+1)*...);}intmain(){std::coutfoo(std::make_index_sequence20())std::endl;}历史学家版本:
(voidmain()有没有嗅到浓厚的历史气息?)
#includestdio.hvoidmain(void){inti;longlongj;for(i=1,j=1;i=20;j*=i++);printf("%lld",j);}敏捷开发上线1.0版本:
(可以说是非常敏捷了)
#includestdio.hintmain(){//printf("%d",1*2*3*4*5*6*7*8*9*10);printf("%lld",(longlong)1*2*3*4*5*6*7*8*9*10*11*12*13*14*15*16*17*18*19*20);}面向对象专家版本:
(好家伙,一个简单的问题,愣是祭出了接口、继承、虚函数、虚继承、智能指针等一大堆东西出来,这很面向对象)
#includeiostream#includestring#includememorystructIBaseInterface{virtual~IBaseInterface()=0;};inlineIBaseInterface::~IBaseInterface()=default;structIDataProvider:virtualpublicIBaseInterface{virtualintfirst()=0;virtualintlast()=0;virtualintnext(intv)=0;};structICalculator:virtualpublicIBaseInterface{virtuallonglongcalc(IDataProvider*)=0;};structIPrinter:virtualpublicIBaseInterface{virtualvoidprint(conststd::string)=0;};structISerializer:virtualpublicIBaseInterface{virtualstd::stringserialize(longlongvalue)=0;};structIRunnable:virtualpublicIBaseInterface{virtualvoidrun()=0;};classFoo:virtualpublicIRunnable{std::shared_ptrIDataProviderm_dp;std::shared_ptrICalculatorm_c;std::shared_ptrISerializerm_s;std::shared_ptrIPrinterm_p;public:Foo(std::shared_ptrIDataProviderdp,std::shared_ptrICalculatorc,std::shared_ptrISerializers,std::shared_ptrIPrinterp):m_dp(std::move(dp)),m_c(std::move(c)),m_s(std::move(s)),m_p(std::move(p)){}voidrun()override{returnm_p-print(m_s-serialize(m_c-calc(m_dp.get())));}};classDefaultSerializer:virtualpublicISerializer{public:std::stringserialize(longlongvalue)override{returnstd::to_string(value);}};classStreamPrinter:virtualpublicIPrinter{std::ostreamm_os;public:explicitStreamPrinter(std::ostreamos):m_os(os){}voidprint(conststd::strings)override{m_ossstd::endl;}};classMultiplyAccumulateCalculator:virtualpublicICalculator{public:longlongcalc(IDataProvider*dp)override{inti=dp-first();longlongj=i;doj*=(i=dp-next(i));while(i!=dp-last());returnj;}};intmain(){structMyDataProvider:virtualpublicIDataProvider{intfirst()override{return1;}intlast()override{return20;}intnext(intv)override{returnv+1;}};Foofoo(std::make_sharedMyDataProvider(),std::make_sharedMultiplyAccumulateCalculator(),std::make_sharedDefaultSerializer(),std::make_sharedStreamPrinter(std::cout));foo.run();}提前优化的并行版本:
(一看就是精通底层技术的大佬,把CPU拿捏得死死的)
#includeiostream#includexmmintrin.hdoublefoo(intx){__ma={1.0f,2.0f,3.0f,4.0f};__mb={4.0f,4.0f,4.0f,4.0f};__mc={1.0f,1.0f,1.0f,1.0f};for(inti=0;ix/4;++i,a=_mm_add_ps(a,b))c=_mm_mul_ps(c,a);for(inti=x%4;i4;++i)a[i]=1.0f;c=_mm_mul_ps(c,a);return(double)c[0]*(double)c[1]*(double)c[2]*(double)c[3];}intmain(){std::coutfoo(20)std::endl;}黑魔法版本:
(能看懂这段代码的,都不是普通人!)
#includeiostream#includenumeric#includevector#includefunctionalintmain(){std::vectorintv(std::atoi(std::end(__DATE__)-(__LINE__)/2)-1);//年,第六行std::iota(v.begin(),v.end(),1);std::coutstd::accumulate(v.begin(),v.end(),1ull,std::multiplies())std::endl;}“宏孩儿”元编程版:
(当年看各种C++框架中,排山倒海一样的宏定义,简直令人发指)
#includeboost/preprocessor.hpp//由于boost.preprocessor仅提供以下的整数运算//所以使用sequence来(十位个位)(千位百位)(十万位万位)的方式来表示大整数。//不进位加法:(77)(66)(55)+(44)(33)(22)=()(99)(77)#definePP_ADD_N_N_CARRY_OP(R,DATA,I,ELEM)(BOOST_PP_ADD(BOOST_PP_SEQ_ELEM(I,DATA),ELEM))#definePP_ADD_N_N_CARRY(SEQ_A,SEQ_B)BOOST_PP_SEQ_FOR_EACH_I(PP_ADD_N_N_CARRY_OP,SEQ_A,SEQ_B)//进位加法:()(99)(77)=(21)(0)(78)//注意SEQ_A的长度要比SEQ_B长#definePP_ADD_N_N_OP(S,STATE,ELEM_CARRY)\BOOST_PP_SEQ_PUSH_FRONT(\BOOST_PP_SEQ_REPLACE(STATE,0,BOOST_PP_MOD(BOOST_PP_ADD(BOOST_PP_SEQ_HEAD(STATE),ELEM_CARRY),)),\BOOST_PP_DIV(BOOST_PP_ADD(BOOST_PP_SEQ_HEAD(STATE),ELEM_CARRY),)\)#definePP_ADD_N_N(SEQ_A,SEQ_B)BOOST_PP_SEQ_REVERSE(BOOST_PP_SEQ_FOLD_LEFT(PP_ADD_N_N_OP,BOOST_PP_SEQ_NIL(0),PP_ADD_N_N_CARRY(SEQ_A,SEQ_B)))//没什么好说的,X*N=X+X+X+X+X+...+X#definePP_MUL_N_1_EXP_OP(Z,I,DATA)(DATA)#definePP_MUL_N_1_EXP(SEQ_N,N)BOOST_PP_REPEAT(N,PP_MUL_N_1_EXP_OP,SEQ_N)#definePP_MUL_N_1_MYOP(S,STATE,ITEM)PP_ADD_N_N(STATE,ITEM)#definePP_MUL_N_1_FWD(EXP)BOOST_PP_SEQ_FOLD_LEFT(PP_MUL_N_1_MYOP,BOOST_PP_SEQ_HEAD(EXP),BOOST_PP_SEQ_TAIL(EXP))#definePP_MUL_N_1(SEQ_N,N)PP_MUL_N_1_FWD(PP_MUL_N_1_EXP(SEQ_N,N))#defineFACT5PP_MUL_N_1(PP_MUL_N_1(PP_MUL_N_1(PP_MUL_N_1((1),2),3),4),5)#defineFACT10PP_MUL_N_1(PP_MUL_N_1(PP_MUL_N_1(PP_MUL_N_1(PP_MUL_N_1(FACT5,6),7),8),9),10)#defineFACT15PP_MUL_N_1(PP_MUL_N_1(PP_MUL_N_1(PP_MUL_N_1(PP_MUL_N_1(FACT10,11),12),13),14),15)#defineFACT20PP_MUL_N_1(PP_MUL_N_1(PP_MUL_N_1(PP_MUL_N_1(PP_MUL_N_1(FACT15,16),17),18),19),20)#defineFACT25PP_MUL_N_1(PP_MUL_N_1(PP_MUL_N_1(PP_MUL_N_1(PP_MUL_N_1(FACT20,21),22),23),24),25)static_assert(false,BOOST_PP_STRINGIZE(FACT10));真·模板元编程版本
(泛型编程,码不惊人死不休)
#includeiostream#includeiomanip#includetype_traitsusingBaseType_t=longlong;constexprBaseType_tlgBase=9;//注意00*00刚刚好小于int的取值范围constexprBaseType_tBase=0000000;//注意00*00刚刚好小于int的取值范围//大整数的表示templateBaseType_t...IstructBigInteger{usingtype=BigInteger;};//连接templateclassT1,classT2structBI_Cat;templateBaseType_t...I1,BaseType_t...I2structBI_CatBigIntegerI1...,BigIntegerI2...:BigIntegerI1...,I2...{};//左移一个单元(即*Base)templateclassTstructBI_SHL;templateBaseType_t...IstructBI_SHLBigIntegerI...:BigIntegerI...,0{};//去除开头的0templateclassTstructBI_Remove_Zeros:T{};templateBaseType_t...IstructBI_Remove_ZerosBigInteger0,I...:BI_Remove_ZerosBigIntegerI...{};//填充0到N个单元templateintX,classISstructBI_Fill_Impl;templateintX,classT,T...IstructBI_Fill_ImplX,std::integer_sequenceT,I...:BigInteger(I,X)...{};templateintSizestructBI_Fill_Zeros:BI_Fill_Impl0,std::make_index_sequenceSize{};templateclassT,intNstructBI_Resize;templateBaseType_t...I,intNstructBI_ResizeBigIntegerI...,N:BI_CattypenameBI_Fill_ZerosN-sizeof...(I)::type,BigIntegerI...{};//返回较大的数值templateintA,intBstructint_min:std::integral_constantint,(AB?B:A){};//非进位加法:先把两个数的位数改成一样的然后依次相加templateclassA,classB,classShouldResizestructBI_AddNotCarry_Impl;templateBaseType_t...I1,BaseType_t...I2structBI_AddNotCarry_ImplBigIntegerI1...,BigIntegerI2...,std::true_type:BigInteger(I1+I2)...{};templateBaseType_t...I1,BaseType_t...I2structBI_AddNotCarry_ImplBigIntegerI1...,BigIntegerI2...,std::false_type:BI_AddNotCarry_ImpltypenameBI_ResizeBigIntegerI1...,int_minsizeof...(I1),sizeof...(I2)::value::type,typenameBI_ResizeBigIntegerI2...,int_minsizeof...(I1),sizeof...(I2)::value::type,std::true_type{};templateclassA,classBstructBI_AddNotCarry;templateBaseType_t...I1,BaseType_t...I2structBI_AddNotCarryBigIntegerI1...,BigIntegerI2...:BI_AddNotCarry_ImplBigIntegerI1...,BigIntegerI2...,std::bool_constantsizeof...(I1)==sizeof...(I2){};//判断是否为0templateclassYstructBI_IsZero;templateBaseType_t...IstructBI_IsZeroBigIntegerI...:std::bool_constant((I==0)...){};//自动进位templateclassAstructBI_Carry;templateclassA,classBstructBI_Add:BI_CarrytypenameBI_AddNotCarryA,B::type{};templateclassMod,classDiv,classShouldCalc=typenameBI_IsZeroDiv::typestructBI_Carry_Impl;templateclassMod,classDivstructBI_Carry_ImplMod,Div,std::true_type:Mod{};templateclassMod,classDivstructBI_Carry_ImplMod,Div,std::false_type:BI_AddMod,typenameBI_SHLDiv::type{};templateBaseType_t...IstructBI_CarryBigIntegerI...:BI_Remove_ZerostypenameBI_Carry_ImplBigInteger(I%Base)...,BigInteger(I/Base)...::type{};//乘以X并自动进位templateclassA,intXstructBI_MulX;templateBaseType_t...I1,intXstructBI_MulXBigIntegerI1...,X:BI_CarryBigInteger(I1*X)...{};//计算阶乘templateintXstructBI_Fact:BI_MulXtypenameBI_FactX-1::type,X{};templatestructBI_Fact0:BigInteger1{};templateBaseType_t...Istd::ostreamoperator(std::ostreamout,BigIntegerI...){return((outstd::setfill(0)Istd::setw(lgBase)),...);}intmain(){std::couttypenameBI_Fact20::type()std::endl;}
原回答: