阶乘的后3个非零数字

问题描述

有人可以用Java中的示例代码帮助我如何从大阶乘中找到最后3个非零数字吗? 例如12! :-479001600 = 16 10! :-3628800 = 288

解决方法

以下函数计算阶乘

private static BigInteger factorial(int n) {
    return IntStream.rangeClosed(1,n)
            .mapToObj(BigInteger::valueOf)
            .collect(Collectors.reducing(BigInteger.ONE,BigInteger::multiply));
}

此函数计算后3个非零数字

private static BigInteger last3NonzeroDigits(BigInteger n) {
    while (n.mod(BigInteger.TEN).equals(BigInteger.ZERO)) {
        n = n.divide(BigInteger.TEN);
    }
    return n.mod(BigInteger.valueOf(1000));
}
  • 删除结尾的零:最后一位为0(除以10,因此i%10 = 0),除以10
  • 从结果数字中,提取(最多)最后3位数字(i%1000)

测试:

for (int i = 1; i <= 15; i++) {
    BigInteger f = factorial(i);
    System.out.println(i+"! = "+f + " -> " + last3NonzeroDigits(f));
}

输出:

1! = 1 -> 1
2! = 2 -> 2
3! = 6 -> 6
4! = 24 -> 24
5! = 120 -> 12
6! = 720 -> 72
7! = 5040 -> 504
8! = 40320 -> 32
9! = 362880 -> 288
10! = 3628800 -> 288
11! = 39916800 -> 168
12! = 479001600 -> 16
13! = 6227020800 -> 208
14! = 87178291200 -> 912
15! = 1307674368000 -> 368
,

您可以将数字映射到字符串,在数字上循环,找到可以找到最多三个非零数字的最后一个索引,最后可以返回索引并打印最后的数字作为结果。我已经编写了一些代码,并编写了方法findLastIndex以获取索引:

fun findLastIndex(num: String): Int {
    var zero = true
    var counter = 0
    val reversedNum = num.reversed()
    
    for(i in 0 until num.length){
        if(!reversedNum[i].equals('0')){
            counter++
            zero = false;
        }
        
        if((reversedNum[i].equals('0') || counter >= 3) && !zero){
            return num.length - i - 1
        }
    }
    
    return 0
}

现在您可以调用该方法并打印最后一个非零数字:

val num = 479001600
val numString = num.toString()
val index = findLastIndex(numString)
println(numString.substring(index).replace("0",""))

您可以在kotlin playground中对其进行测试。用Java进行映射应该很容易。对于reverse方法,您可以查看以下article。或者您可以反转for循环。希望对您有所帮助。