微軟面試題---階乘問題

 階乘是個很有意思的東西,可能很多朋友看到關於他的計算就怕了,其實沒什麼,看完下面兩個問題您應該有底了。

        1.       給定一個 N ,求出N!末尾有多少個零,比如 N=10,N!=3628800,N!末尾有兩個零。
2.       N!的二進制表示中最低爲1的位置,比如 11010010, 最低爲1的位置爲2

問題一解法:

    在上一個 blog 中介紹的子數組乘積最大值的問題中,有朋友考慮到溢出的問題,在這個問題中,我們從那些數相乘能得到10這個命題開始思考。比如N=K×10m那麼N!後面就有m個零。這個問題轉化爲將N!進行分解,如N=2a×3b×5c很顯然 10=2×5,那麼零的個數m=min(a,c), 一個數能夠被2整除的機率比5要大很多因此 m=c,因此轉化爲求 c的問題,具體算法如:

 1publicclass factorial {
 2

 3    privatestaticint zeroNum(int n) 
{
 4

 5       int ret = 0
;
 6

 7       for (int i = 1; i <= n; i++
{
 8

 9           int j =
 i;
10

11           while (j % 5 == 0
{
12

13              ret++
;
14

15              j /= 5
;
16

17           }

18
19       }

20
21
       returnret;
22

23    }

24
25    privatestatic BigInteger fac(long n) 
{
26

27       BigDecimal a = new BigDecimal(1
);
28

29
       BigDecimal b;
30

31       for (long i = 1; i <= n; i++
{
32

33           b = new
 BigDecimal(i);
34

35           a =
 a.multiply(b);
36

37       }

38
39       return
 a.toBigInteger();
40

41    }

42

問題二解法:

我們都知道一個數除以2可以表示爲 N>>1,即向右移動一位。這個問題轉化爲求 N! 含有2的質因數的個數問題。

 1    staticclass PrimeFactor {
 2

 3       publicstaticint primeFactor(int n) 
{
 4

 5           int ret = 0
;
 6

 7           while (n != 0
{
 8

 9              n >>= 1
;
10

11              ret +=
 n;
12

13           }

14
15           return ret + 1
;
16

17       }

18
19       publicstatic String binaryString(int n) 
{
20

21           return
 Integer.toBinaryString(fac(n).intValue());
22

23       }

24
25    }

26

完整程序:

  1package org.blogjava.arithmetic;
  2

  3import
 java.math.BigDecimal;
  4

  5import
 java.math.BigInteger;
  6

  7
/**
  8
  9 * @author
 Jack.Wang
 10

 11 * @see http://jack2007.blogjava.net/

 12
 13 */

 14
 15public class factorial 
{
 16

 17       private static int zeroNum(int n) 
{
 18

 19              int ret = 0
;
 20

 21              for (int i = 1; i <= n; i++
{
 22

 23                     int j =
 i;
 24

 25                     while (j % 5 == 0
{
 26

 27                            ret++
;
 28

 29                            j /= 5
;
 30

 31                     }

 32
 33              }

 34
 35              return
 ret;
 36

 37       }

 38
 39       private static BigInteger fac(long n) 
{
 40

 41              BigDecimal a = new BigDecimal(1
);
 42

 43
              BigDecimal b;
 44

 45              for (long i = 1; i <= n; i++
{
 46

 47                     b = new
 BigDecimal(i);
 48

 49                     a =
 a.multiply(b);
 50

 51              }

 52
 53              return
 a.toBigInteger();
 54

 55       }

 56
 57       static class PrimeFactor 
{
 58

 59              public static int primeFactor(int n) 
{
 60

 61                     int ret = 0
;
 62

 63                     while (n != 0
{
 64

 65                            n >>= 1
;
 66

 67                            ret +=
 n;
 68

 69                     }

 70
 71                     return ret + 1
;
 72

 73              }

 74
 75              public static String binaryString(int n) 
{
 76

 77                     return
 Integer.toBinaryString(fac(n).intValue());
 78

 79              }

 80
 81       }

 82
 83       public static void main(String[] args) 
{
 84

 85              System.out.println("12!爲" + fac(12+ ",後面零的個數爲" + zeroNum(12
));
 86

 87              System.out.println("12!的二進制爲" + PrimeFactor.binaryString(12+ ",1的位置"

 88
 89                            + PrimeFactor.primeFactor(12
));
 90

 91       }

 92
 93       
/**
 94
 95
        out: 
 96

 97
        12!爲479001600,後面零的個數爲2
 98

 99
        12!的二進制爲11100100011001111110000000000,1的位置11
100

101        */

102
103}

104
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章