首页 新闻 会员 周边

用程序解决一数学问题, 给出一个可行的算法描述就行.

0
悬赏园豆:100 [已解决问题] 解决于 2008-12-15 16:31

使n! 是不超过1000位十进制数的n的最大值是什么?

使用的语言可以是C  C++  C#  Java  JavaScript 

Liu Changfeng的主页 Liu Changfeng | 初学一级 | 园豆:60
提问于:2008-12-10 14:42
< >
分享
最佳答案
0

确实杀死不少脑细胞。写了1个小时才搞定。

West 那个方法不行,因为 decimal 只有128 位,我这个不限位数,只要你机器够快。

计算的结果

不超过1000位 是 450!

不超过2000位 是 808!

不超过3000位 是 1143!

 

using System;
using System.Collections.Generic;
using System.Text;

namespace TestFactorial
{
    /// <summary>
    /// 10机制正整数类
    /// </summary>
    public class DecimalNumber
    {
        List<byte> _Data;

        public List<byte> Data
        {
            get
            {
                return _Data;
            }
        }

        public int Length
        {
            get
            {
                return _Data.Count;
            }
        }

        public DecimalNumber()
        {
            _Data = new List<byte>();
        }

        public DecimalNumber(byte[] data)
        {
            foreach (byte b in data)
            {
                System.Diagnostics.Debug.Assert(b >= 0 && b <= 9);
            }

            _Data = new List<byte>(data);
        }

        public DecimalNumber(List<byte> data)
        {
            foreach (byte b in data)
            {
                System.Diagnostics.Debug.Assert(b >= 0 && b <= 9);
            }

            _Data = data;
        }

        /// <summary>
        /// 1位10机制数和10进制序列相乘
        ///
        /// </summary>
        /// <param name="s">10进制序列</param>
        /// <param name="d">1位10机制数</param>
        /// <param name="power">10的幂数</param>
        /// <returns></returns>
        private static List<byte> Multiply(List<byte> s, byte d, int power)
        {
            System.Diagnostics.Debug.Assert(power >= 0);
            System.Diagnostics.Debug.Assert(d >= 0 && d <= 9);

            List<byte> result = new List<byte>();

            for (int i = 0; i < power; i++)
            {
                result.Add(0);
            }

            byte carry = 0; //进位

            foreach (byte si in s)
            {
                System.Diagnostics.Debug.Assert(si >= 0 && si <= 9);

                byte r = (byte)(si* d + carry);
                byte m = (byte)(r % 10);
                carry = (byte)(r / 10);
                result.Add(m);
            }

            if (carry > 0)
            {
                result.Add(carry);
            }


            return result;
        }

        /// <summary>
        /// 两个10进制序列相加
        /// </summary>
        /// <param name="s1">序列1</param>
        /// <param name="s2">序列2</param>
        /// <returns>相加后的序列</returns>
        private static List<byte> Plus(List<byte> s1, List<byte> s2)
        {
            List<byte> result = new List<byte>();

            int c1 = s1.Count;
            int c2 = s2.Count;

            if (c1 > c2)
            {
                for (int i = 0; i < c1 - c2; i++)
                {
                    s2.Add(0);
                }
            }
            else if (c1 < c2)
            {
                for (int i = 0; i < c2 - c1; i++)
                {
                    s1.Add(0);
                }
            }

            byte carry = 0; //进位

            for (int i = 0; i < s1.Count; i++)
            {
                System.Diagnostics.Debug.Assert(s1[i] >= 0 && s1[i] <= 9);
                System.Diagnostics.Debug.Assert(s2[i] >= 0 && s2[i] <= 9);

                byte r = (byte)(s1[i] + s2[i] + carry);
                byte m = (byte)(r % 10);
                carry = (byte)(r / 10);
                result.Add(m);
            }

            if (carry > 0)
            {
                result.Add(carry);
            }

            return result;
        }

        public static implicit operator DecimalNumber(string value)
        {
            List<byte> data = new List<byte>();

            for (int i = value.Length - 1; i >= 0; i--)
            {
                data.Add(byte.Parse(value[i].ToString()));
            }

            return new DecimalNumber(data);
        }

        public static implicit operator DecimalNumber(int value)
        {
            System.Diagnostics.Debug.Assert(value >= 0);
            return value.ToString();
        }

        public static DecimalNumber operator ++(DecimalNumber d)
        {
            return d + new DecimalNumber(new byte[] {1});
        }

        public static DecimalNumber operator +(DecimalNumber d1, int d2)
        {
            System.Diagnostics.Debug.Assert(d2 >= 0);

            return d1 + d2.ToString();
        }

        public static DecimalNumber operator+(DecimalNumber d1, DecimalNumber d2)
        {
            return new DecimalNumber(Plus(d1.Data, d2.Data));
        }

        public static DecimalNumber operator*(DecimalNumber d1, DecimalNumber d2)
        {
            List<List<byte>> multiplicationSerial = new List<List<byte>>();

            for (int i = 0; i < d1.Data.Count; i++)
            {
                multiplicationSerial.Add(Multiply(d2.Data, d1.Data[i], i));
            }

            List<byte> result = new List<byte>();

            foreach(List<byte> s in multiplicationSerial)
            {
                result = Plus(s, result);
            }
           
            return new DecimalNumber(result);
        }

        public override string ToString()
        {
            StringBuilder str = new StringBuilder();

            for (int i = _Data.Count - 1; i >= 0 ; i--)
            {
                str.Append(_Data[i].ToString());
            }

            return str.ToString();
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            int d = 1;
            DecimalNumber factorial = 1;

            while (factorial.Length < 3)
            {
                d++;
                factorial = factorial * d;
                //Console.WriteLine(factorial);
                //Console.WriteLine(d);
            }

            Console.WriteLine(d);
        }
    }
}

eaglet | 专家六级 |园豆:17139 | 2008-12-10 19:22
其他回答(4)
0

    public static decimal Factorial(decimal n)
    {
        if (n == 1)
            return 1;
        else
            return n * Factorial(n - 1);
    }

 

        for (int i = 1; ; i++)
        {
            if (Factorial(i).ToString().Length > 1000)
            {

      //输出 i
                break;
            }
        }

West | 园豆:1095 (小虾三级) | 2008-12-10 15:19
0

xuexi le....

Jared.Nie | 园豆:1940 (小虾三级) | 2008-12-10 17:19
0

       我的简单,呵呵

        int factor=1;
        int i;

        for ( i = 1; factor < 1000; i++)
        {

            factor = factor * i;

        }

console.WriteLine(i);

长风一剑 | 园豆:29 (初学一级) | 2008-12-11 09:36
0

function strSum(a,b)
{
  var sumStr = '';
  var temp = 0;
  var i = a.length-1;
  for(;i>=0;i--)
  {
    var thisNum = a.charAt(i);
    sumStr = (thisNum*b+temp)%10+''+sumStr;
    temp = Math.floor((thisNum*b+temp)/10);
  }
  sumStr = temp+''+sumStr;
  sumStr = sumStr.replace(/^0*/,'');
  return sumStr;
}
var numSumStr = '1';
for(var num = 1;numSumStr.length<1000;num++)
{
  numSumStr = strSum(numSumStr,num+'')
  document.write(num + ':'+ ':' + numSumStr + '<br/>');
}

javaScript的~~ 运行一下试试吧~~

还可以优化一下。把未尾的0去掉。只记0的个数。

结果跟eaglet的一样。

BB_Coder | 园豆:797 (小虾三级) | 2008-12-11 15:17
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册