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。
<pre><code>` 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
}`</code></pre>

第二种解法 Z =[N/5] + [N/52] + [N/53] + …
[N/5] 表示不大于N的的数中5的倍数贡献一个5, [N/52] 表示不大于N的数中52的倍数在贡献一个5……
<pre><code>` func compute2(num:Int) -> Int {

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

最低位1的位置

将二进制数字除以2,若是余数是0则为偶数,余数是非0则是奇数,余数即为最后一位的代表的值.所以判断N!的二进制表示中最低位为1的位置的问题可以转换为求N!中含有质因数2的个数的问题。即位置为N!含有质因数2的个数加1.
N!中含有质因数2的个数等于:[N/2]+[N/4]+[N/8]+…
<pre><code>func lowestOne(num:Int)->Int { var count:Int = 0 var temp:Int = num while temp > 0 { temp >>= 1 count += temp } return count }</code></pre>
两个问题类似,问题1的第一种解法同样适用于第二种:
<pre><code>` 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
}`</code></pre>

测试代码:
<pre><code>`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)")`</code></pre>


FlyElephant.png

题外话,判断数字是不是2的整数次幂?
<pre><code>func isPowerOfBinary(num:Int) -> Bool { return num > 0 && (num & (num - 1)) == 0 }</code></pre>

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容