我能算到的阶乘有多大(六)

Author:水如烟 

哇噻。真快了好多。

算到1000的阶乘只用25秒。且全是在一个线程里面。

现在算10000的阶乘不是问题了.在另一台机运算了一个小时,算到了9300多,数据位33000多.这时的速度约一秒一个.

算到36106时,数据位为148879,现在的速度是2秒一个,其中包括了写入数据库的时间. 

下面的代码在处理分拆时还是不妥的.

现在需要转到值片断的表示问题.

数据一大,需要考虑的问题真的多多.

< Serializable() >  _
Public   Class  MathsUnit

    
Private  gMathUnits  As   New  Collections.ObjectModel.Collection( Of  MathUnit)  ' 运算单元组
     Private  gLocalIndex  As   Integer   =   0   ' 当前组最后运算单元在全部运算单元中的位置。从最后往前数(就是从个位开始数)。

    
Private  gHasCarry  As   Boolean   =   False   ' 是否有进位
     Private  gCarry  As   New  MathUnit( True ' 进位运算单元

    
Public   ReadOnly   Property  fullvalue()  As   String
        
Get
            
Dim  b  As   New  system.text.stringbuilder
            
If  ghascarry  Then  b.append(gcarry.value)
            b.append(value)
            
Return  b.tostring
        
End   Get
    
End Property

    
Public   ReadOnly   Property  Value()  As   String
        
Get
            
Dim  b  As   New  System.Text.StringBuilder
            
For  i  As   Integer   =   0   To  gMathUnits.Count  -   1
                b.Append(gMathUnits(i).Value)
            
Next
            
Return  b.ToString
        
End   Get
    
End Property


    
Public   Sub  SetValue( ByVal  strUnit  As  StringUnit)
        
Me .Clear()

        
Dim  strArray()  As   String   =  Information.SplitValueToArray(strUnit.Value)

        
Dim  mMathUnit  As  MathUnit
        
For  i  As   Integer   =   0   To  strArray.Length  -   1

            
If  i  =   0   Then
                mMathUnit 
=   New  MathUnit( True )
            
Else
                mMathUnit 
=   New  MathUnit
            
End   If

            mMathUnit.SetValue(strArray(i))
            
Me .gMathUnits.Add(mMathUnit)
        
Next

        gLocalIndex 
=  strUnit.LocalIndex
    
End Sub

    
Private   Sub  Clear()
        gMathUnits.Clear()
        gLocalIndex 
=   0
        gHasCarry 
=   False
        gCarry.Clear()
    
End Sub

    
Public   Function  Clone()  As  MathsUnit
        
Return  CommonFunction.Clone( Of  MathsUnit)( Me )
    
End Function

    
Public   Sub  CopyFrom( ByVal  unit  As  MathsUnit)
        
With  unit

            gMathUnits.Clear()

            
For  i  As   Integer   =   0   To  .gMathUnits.Count  -   1
                gMathUnits.Add(.gMathUnits(i).Clone)
            
Next

            gLocalIndex 
=  .gLocalIndex

            gHasCarry 
=  .gHasCarry
            gCarry 
=  .gCarry.Clone

        
End   With
    
End Sub

End Class

 

Partial   Class  MathsUnit

    
Public   Shared  Operator  = ( ByVal  a  As  MathsUnit,  ByVal  b  As  MathsUnit)  As   Boolean
        
If  a.gLocalIndex  <>  b.gLocalIndex  Then   Return   False

        
If  a.gMathUnits.Count  <>  b.gMathUnits.Count  Then   Return   False

        
For  i  As   Integer   =   0   To  a.gMathUnits.Count  -   1
            
If  a.gMathUnits(i)  <>  b.gMathUnits(i)  Then   Return   False
        
Next

        
If  a.gHasCarry  <>  b.gHasCarry  Then   Return   False

        
If  a.gCarry  <>  b.gCarry  Then   Return   False

        
Return   True
    
End  Operator

    
Public   Shared  Operator  <> ( ByVal  a  As  MathsUnit,  ByVal  b  As  MathsUnit)  As   Boolean

        
If  a.gLocalIndex  <>  b.gLocalIndex  Then   Return   True

        
If  a.gMathUnits.Count  <>  b.gMathUnits.Count  Then   Return   True

        
For  i  As   Integer   =   0   To  a.gMathUnits.Count  -   1
            
If  a.gMathUnits(i)  <>  b.gMathUnits(i)  Then   Return   True
        
Next

        
If  a.gHasCarry  <>  b.gHasCarry  Then   Return   True

        
If  a.gCarry  <>  b.gCarry  Then   Return   True

        
Return   True

    
End  Operator

    
Public   Shared  Operator  > ( ByVal  a  As  MathsUnit,  ByVal  b  As  MathsUnit)  As   Boolean

        
If  a.gLocalIndex  >  b.gLocalIndex  Then   Return   True

        
If  a.gLocalIndex  <  b.gLocalIndex  Then   Return   False

        
If  a.gMathUnits.Count  >  b.gMathUnits.Count  Then   Return   True

        
If  a.gMathUnits.Count  <  b.gMathUnits.Count  Then   Return   False

        
For  i  As   Integer   =   0   To  a.gMathUnits.Count  -   1

            
If  a.gMathUnits(i)  >  b.gMathUnits(i)  Then   Return   True

            
If  a.gMathUnits(i)  <  b.gMathUnits(i)  Then   Return   False
        
Next


        
Return  a.gCarry  >  b.gCarry

    
End  Operator

    
Public   Shared  Operator  >= ( ByVal  a  As  MathsUnit,  ByVal  b  As  MathsUnit)  As   Boolean
        
If  a.gLocalIndex  >  b.gLocalIndex  Then   Return   True

        
If  a.gLocalIndex  <  b.gLocalIndex  Then   Return   False

        
If  a.gMathUnits.Count  >  b.gMathUnits.Count  Then   Return   True

        
If  a.gMathUnits.Count  <  b.gMathUnits.Count  Then   Return   False

        
For  i  As   Integer   =   0   To  a.gMathUnits.Count  -   1

            
If  a.gMathUnits(i)  >  b.gMathUnits(i)  Then   Return   True

            
If  a.gMathUnits(i)  <  b.gMathUnits(i)  Then   Return   False
        
Next


        
Return  a.gCarry  >=  b.gCarry
    
End  Operator

    
Public   Shared  Operator  < ( ByVal  a  As  MathsUnit,  ByVal  b  As  MathsUnit)  As   Boolean
        
If  a.gLocalIndex  >  b.gLocalIndex  Then   Return   False

        
If  a.gLocalIndex  <  b.gLocalIndex  Then   Return   True

        
If  a.gMathUnits.Count  >  b.gMathUnits.Count  Then   Return   False

        
If  a.gMathUnits.Count  <  b.gMathUnits.Count  Then   Return   True

        
For  i  As   Integer   =   0   To  a.gMathUnits.Count  -   1

            
If  a.gMathUnits(i)  >  b.gMathUnits(i)  Then   Return   False

            
If  a.gMathUnits(i)  <  b.gMathUnits(i)  Then   Return   True
        
Next


        
Return  a.gCarry  <  b.gCarry
    
End  Operator

    
Public   Shared  Operator  <= ( ByVal  a  As  MathsUnit,  ByVal  b  As  MathsUnit)  As   Boolean
        
If  a.gLocalIndex  >  b.gLocalIndex  Then   Return   False

        
If  a.gLocalIndex  <  b.gLocalIndex  Then   Return   True

        
If  a.gMathUnits.Count  >  b.gMathUnits.Count  Then   Return   False

        
If  a.gMathUnits.Count  <  b.gMathUnits.Count  Then   Return   True

        
For  i  As   Integer   =   0   To  a.gMathUnits.Count  -   1

            
If  a.gMathUnits(i)  >  b.gMathUnits(i)  Then   Return   False

            
If  a.gMathUnits(i)  <  b.gMathUnits(i)  Then   Return   True
        
Next


        
Return  a.gCarry  <=  b.gCarry
    
End  Operator


    
Public   Shared   Function  Max( ByVal  a  As  MathsUnit,  ByVal  b  As  MathsUnit)  As  MathsUnit
        
If  a  >=  b  Then
            
Return  a
        
Else
            
Return  b
        
End   If
    
End Function

End Class

左、右补位:

Partial   Class  MathsUnit

    
Private   Sub  RightMakeUpUnits( ByVal  amount  As   Integer )
        
If  amount  <   1   Then   Exit Sub

        
If  gLocalIndex  -  amount  <   0   Then   Throw   New  Exception(Information.MSG_UNIT_MUTIPLY_MOVE_OVERFLOW)

        
For  i  As   Integer   =   0   To  amount  -   1
            gMathUnits.Add(
New  MathUnit)
        
Next

        gLocalIndex 
-=  amount
    
End Sub

    
Private   Sub  LeftMakeUpUnits( ByVal  amount  As   Integer )
        
If  amount  <   1   Then   Exit Sub

        
If  gMathUnits.Count  >   0   Then  gMathUnits( 0 ).IsFirstUnitReverse()

        
For  i  As   Integer   =   0   To  amount  -   1
            gMathUnits.Insert(
0 New  MathUnit)
        
Next

        gMathUnits(
0 ).IsFirstUnitReverse()

        
If  gHasCarry  Then
            gMathUnits(amount 
-   1 ).Add(gCarry)

            gCarry.Clear()
            gHasCarry 
=   False
        
End   If
    
End Sub


    
Private   Sub  FullMakeUpUnits( ByVal  unit  As  MathsUnit)
        RightMakeUpUnits(
Me .gLocalIndex  -  unit.gLocalIndex)
        LeftMakeUpUnits(unit.gLocalIndex 
+  unit.gMathUnits.Count  -   Me .gLocalIndex  -   Me .gMathUnits.Count)
    
End Sub

End Class

进位处理:

Partial   Class  MathsUnit

    
Private   Sub  ReferCarry()
        
For  i  As   Integer   =   0   To   Me .gMathUnits.Count  -   1
            ReferCarry(i)
        
Next

        gHasCarry 
=  (gCarry.Value  <>   " 0 " )
    
End Sub

    
Private   Sub  ReferCarry( ByVal  index  As   Integer )
        
Dim  mCurrentMathUnit  As  MathUnit  =  gMathUnits(index)
        
Dim  mPreviousMathUnit  As  MathUnit

        
If  mCurrentMathUnit.HasCarry  Then

            
If  index  =   0   Then
                mPreviousMathUnit 
=  gCarry
            
Else
                mPreviousMathUnit 
=  gMathUnits(index  -   1 )
            
End   If

            mCurrentMathUnit.ReferCarryTo(mPreviousMathUnit)

            
If  mPreviousMathUnit.HasCarry  Then
                ReferCarry(index 
-   1 )
            
End   If

        
End   If
    
End Sub

End Class

 

Partial   Class  MathsUnit

    
Public   Sub  Add( ByVal  unit  As  MathsUnit)
        
If  unit  Is   Nothing   Then   Exit Sub

        
Me .FullMakeUpUnits(unit)

        
Dim  mMathUnitCount  As   Integer   =  unit.gMathUnits.Count
        
Dim  bIndex  As   Integer
        
Dim  k  As   Integer   =   0

        
Dim  CurrentMathUnit  As  MathUnit
        
For  i  As   Integer   =   Me .gMathUnits.Count  -   1   To   0   Step   - 1
            bIndex 
=  mMathUnitCount  -   1   -  k
            
If  bIndex  <   0   Then
                CurrentMathUnit 
=   Nothing
            
Else
                CurrentMathUnit 
=  unit.gMathUnits(bIndex)
            
End   If
            
Me .gMathUnits(i).Add(CurrentMathUnit)
            k 
+=   1
        
Next

        
Me .ReferCarry()

        
If  gHasCarry  Then   Me .LeftMakeUpUnits( 1 )
    
End Sub

    
Public   Shared  Operator  + ( ByVal  a  As  MathsUnit,  ByVal  b  As  MathsUnit)  As  MathsUnit
        
Dim  c  As  MathsUnit  =  a.Clone
        c.Add(b)
        
Return  c
    
End  Operator

End Class

 

Partial   Class  MathsUnit

    
Public   Sub  Multy( ByVal  unit  As  MathsUnit)
        
Dim  mCount  As   Integer   =  unit.gMathUnits.Count
        
Dim  mResultArray(mCount  -   1 As  MathsUnit

        
For  i  As   Integer   =   0   To  mCount  -   1
            mResultArray(i) 
=  MultiplyUnit(unit.gMathUnits(i))
            mResultArray(i).RightMakeUpUnitsWhenMultiply(unit, mCount 
-   1   -  i)
        
Next

        
For  i  As   Integer   =   1   To  mCount  -   1
            mResultArray(
0 ).Add(mResultArray(i))
        
Next

        
Me .CopyFrom(mResultArray( 0 ))
    
End Sub

    
Public   Shared  Operator  * ( ByVal  a  As  MathsUnit,  ByVal  b  As  MathsUnit)  As  MathsUnit
        
Dim  c  As  MathsUnit  =  a.Clone
        c.Multy(b)
        
Return  c
    
End  Operator

    
Private   Function  MultiplyUnit( ByVal  unit  As  MathUnit)  As  MathsUnit
        
Dim  mResult  As  MathsUnit  =   Me .Clone

        
For  i  As   Integer   =   0   To  mResult.gMathUnits.Count  -   1
            mResult.gMathUnits(i).Multy(unit)
        
Next

        mResult.ReferCarry()

        
If  mResult.gHasCarry  Then  mResult.LeftMakeUpUnits( 1 )

        
Return  mResult
    
End Function

    
Private   Sub  RightMakeUpUnitsWhenMultiply( ByVal  b  As  MathsUnit,  ByVal  indexOfMathunitFromLast  As   Integer )
        
Me .gLocalIndex  +=  indexOfMathunitFromLast
    
End Sub

End Class

 

< Serializable() >  _
Public   Class  StringUnit

    
Private  gValue  As   String   =   " 0 "
    
Private  gLocalIndex  As   Integer   =   0

    
Sub   New ( ByVal  value  As   String ByVal  localIndex  As   Integer )
        gValue 
=  value
        gLocalIndex 
=  localIndex
    
End Sub

    
Public   ReadOnly   Property  Value()  As   String
        
Get
            
Return  gValue
        
End   Get
    
End Property

    
Public   ReadOnly   Property  LocalIndex()  As   Integer
        
Get
            
Return  gLocalIndex
        
End   Get
    
End Property
End Class
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值