jjccx

jjccx's blog
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

老生常谈:1000的阶乘

Posted on 2007-05-20 15:43  jjccx  阅读(1009)  评论(1编辑  收藏  举报
前几天在一家公司的网上笔试,其中有这样一道题,计算1000的阶乘,其它没有具体要求,后来我写程序如下:

#include <iostream>

#include <tchar.h>

 

class CFactorialCalculator

{

public:

   CFactorialCalculator()

      : iIncBufferSize(1024)

   {

      ret1 = ret2 = NULL;

      iBufferSize = 0;

   }

   ~CFactorialCalculator()

   {

      delete[] ret1;

      delete[] ret2;

   }

   bool Calc(int n)

   {

      if(n < 0)

         return false;

 

      if(!ret1 || !ret2)

      {

         delete[] ret1; delete[] ret2;

         AllocResult();

      }

      else

      {

         memset(ret1, 0, iBufferSize);

         memset(ret2, 0, iBufferSize);

      }

 

      *ret1 = *ret2

         = top = 1;

 

      while(true)

      {

         if(n <= 1) break;

         if(!AppendMulti(n--)) return false;

      }

 

      return true;

   }

 

   inline int GetResultCount() { return top; }

   inline char* GetResult() { return ret1; }

 

   // Helper

   static void PrintToConsole(

      int n, int iResultCount, char* szFactorialResult)

   {

      printf("%d!=", n);

 

      for(int i = iResultCount - 1; i >= 0; i--)

      {

         printf("%d", szFactorialResult[i]);

      }

 

      printf("\n");

   }

 

protected:

   bool AllocResult()

   {

      int iNewSize = iBufferSize + iIncBufferSize;

 

      char* r1 = new char[iNewSize];

      char* r2 = new char[iNewSize];

 

      if(!r1 || !r2)

      {

         delete[] r1; delete[] r1;

         return false;

      }

 

      memset(r1, 0, iNewSize);

      memset(r2, 0, iNewSize);

 

      if(ret1)

      {

         memcpy(r1, ret1, iBufferSize);

         delete[] ret1;

      }

      if(ret2)

      {

         memcpy(r2, ret2, iBufferSize);

         delete[] ret2;

      }

 

      iBufferSize = iNewSize;

 

      ret1 = r1;

      ret2 = r2;

 

      return true;

   }

 

   bool AppendMulti(int n)

   {

      int i, j = 0;

      int m;

      char* ret;

 

      memset(ret2, 0, top);

 

      while(n > 0)

      {

         m = n % 10;

 

         for(i = 0; i < top; i++)

         {

            if(i + j + 1 >= iBufferSize)

            {

                if(!AllocResult()) return false;

            }

            ret2[i + j] += m * ret1[i];

            if(ret2[i + j] >= 10)

            {

                ret2[i + j + 1] += ret2[i + j] / 10;

                ret2[i + j] %= 10;

            }

         }

 

         n /= 10;

         j++;

      }

 

      top = (ret2[i + j - 1] ? 1 : 0) + i + j - 1;

 

      ret = ret1; ret1 = ret2; ret2 = ret;

 

      return true;

   }

 

private:

   char* ret1;

   char* ret2;

 

   const int iIncBufferSize;

   int iBufferSize;

 

   int top;

};

 

int _tmain(int argc, _TCHAR* argv[])

{

   CFactorialCalculator fc;

 

   int test[] = {

      -1, 0, 1, 4, 10, 11, 100, 459, 750, 1000, 1001

   };

 

   for(int i = 0; i < sizeof(test) / sizeof(int); i++)

   {

      if(fc.Calc(test[i]))

      {

         CFactorialCalculator::PrintToConsole(

            test[i], fc.GetResultCount(),

            fc.GetResult()

            );

      }

      else

      {

         printf("%d!=ERROR\n", test[i]);

      }

   }

 

   return 0;

}