Swift-整数阶乘

(1)给定一个整数N,那么N的阶乘N!末尾有多少个0?比如:N=10,N!=3628800,N!的末尾有2个0。
(2)求N!的二进制表示中最低位为1的位置。

0的个数

首先考虑哪些组合可以得到10即可,考虑哪些数相乘能得到10,N!= K * 10M其中K不能被10整除,则N!末尾有M个0.
对N!进行质因数分解: N!=2X3Y5Z…,因为10=2*5,所以M与2和5的个数即X、Z有关。每一对2和5都可以得到10,故M=min(X,Z)。因为能被2整除的数出现的频率要比能被5整除的数出现的频率高,所以M=Z。

` func compute1(num:Int) -> Int {

    var count:Int = 0
    for i in 1...num {
        var j:Int = i
        
        while j % 5 == 0 {
            count += 1
            j /= 5
        }
    }
    
    return count
}`

第二种解法 Z =[N/5] + [N/52] + [N/53] + …
[N/5] 表示不大于N的的数中5的倍数贡献一个5, [N/52] 表示不大于N的数中52的倍数在贡献一个5……

` func compute2(num:Int) -> Int {

    var count:Int = 0
    var temp:Int = num
    
    while temp > 0 {
        count += temp / 5
        temp /= 5
    }
    return count
}`

最低位1的位置

将二进制数字除以2,若是余数是0则为偶数,余数是非0则是奇数,余数即为最后一位的代表的值.所以判断N!的二进制表示中最低位为1的位置的问题可以转换为求N!中含有质因数2的个数的问题。即位置为N!含有质因数2的个数加1.
N!中含有质因数2的个数等于:[N/2]+[N/4]+[N/8]+…

func lowestOne(num:Int)->Int { var count:Int = 0 var temp:Int = num while temp > 0 { temp >>= 1 count += temp } return count }

两个问题类似,问题1的第一种解法同样适用于第二种:
` func lowestOne1(num:Int) -> Int {

    var count:Int = 0
    for i in 1...num {
        var j:Int = i
        
        while j % 2 == 0 {
            j /= 2
            count += 1
        }
    }
    
    return count
}`

测试代码:

`var result1 = factorial.compute1(num: 20)
print("FlyElephant-10进制0的个数---(result1)")

var result2 = factorial.compute2(num: 20)

print("FlyElephant-10进制0的个数---(result2)")

var result3 = factorial.lowestOne(num: 10)
print("FlyElephant-1的位置---(result3)")

var result4 = factorial.lowestOne1(num: 10)
print("FlyElephant-1的位置---(result4)")`


FlyElephant.png

题外话,判断数字是不是2的整数次幂?

func isPowerOfBinary(num:Int) -> Bool { return num > 0 && (num & (num - 1)) == 0 }

你可能感兴趣的:(Swift-整数阶乘)