Counting trailing zeros of numbers resulted from factorial

后端 未结 10 1586
北荒
北荒 2020-11-30 07:48

I\'m trying to count trailing zeros of numbers that are resulted from factorials (meaning that the numbers get quite large). Following code takes a number, compute the facto

相关标签:
10条回答
  • 2020-11-30 08:39

    You can use a DecimalFormat to format big numbers. If you format your number this way you get the number in scientific notation then every number will be like 1.4567E7 this will make your work much easier. Because the number after the E - the number of characters behind the . are the number of trailing zeros I think.

    I don't know if this is the exact pattern needed. You can see how to form the patterns here

    DecimalFormat formater = new DecimalFormat("0.###E0");
    
    0 讨论(0)
  • 2020-11-30 08:40

    Your task is not to compute the factorial but the number of zeroes. A good solution uses the formula from http://en.wikipedia.org/wiki/Trailing_zeros (which you can try to prove)

    def zeroes(n):
        i = 1
        result = 0
        while n >= i:
            i *= 5
            result += n/i  # (taking floor, just like Python or Java does)
        return result
    

    Hope you can translate this to Java. This simply computes [n / 5] + [n / 25] + [n / 125] + [n / 625] + ... and stops when the divisor gets larger than n.

    DON'T use BigIntegers. This is a bozosort. Such solutions require seconds of time for large numbers.

    0 讨论(0)
  • 2020-11-30 08:47

    I wrote this up real quick, I think it solves your problem accurately. I used the BigInteger class to avoid that cast from double to integer, which could be causing you problems. I tested it on several large numbers over 25, such as 101, which accurately returned 24 zeros.

    The idea behind the method is that if you take 25! then the first calculation is 25 * 24 = 600, so you can knock two zeros off immediately and then do 6 * 23 = 138. So it calculates the factorial removing zeros as it goes.

    public static int count(int number) {
        final BigInteger zero = new BigInteger("0");
        final BigInteger ten = new BigInteger("10");
        int zeroCount = 0;
        BigInteger mult = new BigInteger("1");
        while (number > 0) {
            mult = mult.multiply(new BigInteger(Integer.toString(number)));
            while (mult.mod(ten).compareTo(zero) == 0){
                mult = mult.divide(ten);
                zeroCount += 1;
            }
            number -= 1;
        }
        return zeroCount;
    }
    

    Since you said you don't care about run time at all (not that my first was particularly efficient, just slightly more so) this one just does the factorial and then counts the zeros, so it's cenceptually simpler:

    public static BigInteger factorial(int number) {
        BigInteger ans = new BigInteger("1");
        while (number > 0) {
            ans = ans.multiply(new BigInteger(Integer.toString(number)));
            number -= 1;
        }
        return ans;
    }
    
    public static int countZeros(int number) {
        final BigInteger zero = new BigInteger("0");
        final BigInteger ten = new BigInteger("10");
        BigInteger fact = factorial(number);
        int zeroCount = 0;
        while (fact.mod(ten).compareTo(zero) == 0){
            fact = fact.divide(ten);
            zeroCount += 1;
        }
    }
    
    0 讨论(0)
  • 2020-11-30 08:48

    The best with logarithmic time complexity is the following:

    public int trailingZeroes(int n) {
        if (n < 0)
            return -1;
    
        int count = 0;
        for (long i = 5; n / i >= 1; i *= 5) {
            count += n / i;
        }
    
        return count;
    }
    

    shamelessly copied from http://www.programcreek.com/2014/04/leetcode-factorial-trailing-zeroes-java/

    0 讨论(0)
提交回复
热议问题