日期:2014-05-20  浏览次数:21136 次

阶乘(1000的阶乘,10000的阶乘...)以及大数相乘(几十万位乘几十万位)
大家有兴趣的可以贴出更加简洁明了以及高效的算法

核心函数,可以满足阶乘以及两个大数相乘
1,000的阶乘4秒
10,000的阶乘220秒
100,000的阶乘.... ...(汗,没算完,算了1个半小时算到45,000左右)
大数相乘可以支持到N大(没测试过到底多大,Dictionary把内存撑爆为止吧,呵呵^_^)
核心函数如下:
C# code

 /// <summary>
        /// 将传入的因数X,因数Y的Dictionary中的元素循环进行相乘.
        /// </summary>
        /// <param name="FactorX">因数X</param>
        /// <param name="FactorY">因数Y</param>
        /// <returns>乘积结果的Dictionary</returns>
        static Dictionary<int, int> GetProduct(Dictionary<int, int> FactorX
                                                       , Dictionary<int, int> FactorY)
        {
            Dictionary<int, int> ret = new Dictionary<int, int>(); //乘积,返回结果
            int Carry = 0;          //进位数
            int Product = 0;        //乘积
            int Position = 0;       //位数
            int Number = 0;         //乘积 % 10 取余的余数
            int TempNumber = 0;     //旧值

            //循环历遍因数X中的元素
            foreach (KeyValuePair<int, int> kvpFactorX in FactorX)
            {
                //清除进位数
                Carry = 0;
                //循环历遍因数Y中的元素
                foreach (KeyValuePair<int, int> kvpFactorY in FactorY)
                {
                    //取得乘积,例如 9 * 9 = 81
                    Product = kvpFactorY.Value * kvpFactorX.Value;

                    //取得位数,例如 因数X的第1位 * 因数Y的第1位,那么其乘积所在开始的位数则为2, 
                    //比如 20 * 30 中两个十位数相乘其结果
                    //开始的位数为(2所在位数为1 + 3所在位数为1) = 6所在位数为2,即是600
                    Position = kvpFactorX.Key + kvpFactorY.Key;
                    //取得乘积 % 10 取余的余数
                    Number = Product % 10;
                    //判断乘积结果中该位是否有值,有值则相加,否则插入
                    if (ret.Keys.Contains(Position))
                    {
                        //临时存放旧值
                        TempNumber = ret[Position];
                        //更新当前位的值,当前位值 = (旧值 + 取得乘积 % 10 取余的余数 + 上一次进位数) % 10 取余
                        ret[Position] = (TempNumber + Number + Carry) % 10;
                        //取得当前进位值,當前進位值 = (旧值 + 乘积 + 进位)/10 取整
                        Carry = (int)Math.Floor((TempNumber + Product + Carry) / 10.0);
                    }
                    else
                    {
                        //插入位数,值
                        ret.Add(Position, (Number + Carry) % 10);
                        //取得当前进位值,當前進位值 = (乘积 + 进位)/10 取整
                        Carry = (int)Math.Floor((Product + Carry) / 10.0);
                    }
                }
                //当最后进位数不为0时,需要新增最高位,其值为进位数
                if (Carry != 0) ret.Add(ret.Keys.Max() + 1, Carry);
            }
            return ret;
        }



囧,不允许我输入太多,完整例子看下一楼

------解决方案--------------------
mark
 回复内容太短了!
 回复内容太短了!
 回复内容太短了! 回复内容太短了!
------解决方案--------------------
你的电脑和你有仇吗?
------解决方案--------------------
靠,C#版发帖,真是太长不行,太短也不行啊。。。 。。。

你这种方法利用了技术过的就不再计算的原则?

搞了一段Ruby的,据说Ruby比C#慢了很多倍啊。。。

Python code

def f(n)
  i = 1
  while n > 0
    i *= n
    n -= 1
  end
  return i
end
puts f(1000)

------解决方案--------------------
10000的阶乘,我没有精确计时,我只是心里默念1秒,2秒,居然在第六秒的时候就IO出来了。。。
------解决方案--------------------
探讨
呵呵,抛砖引玉。

引用:
10000的阶乘,我没有精确计时,我只是心里默念1秒,2秒,居然在第六秒的时候就IO出来了。。。

------解决方案--------------------