阶乘的末尾三个非零数字

huangapple go评论80阅读模式
英文:

Last 3 non zero digits from factorial

问题

可以有人帮我用Java编写示例代码,演示如何从大阶乘中找出最后3个非零数字?
例如:12! :479001600 = 16
10! :3628800 = 288

英文:

Can someone help me with the sample code in java how to find last 3 non zero digits from big factorial?
Eg 12! :- 479001600 = 16
10! :- 3628800 =288

答案1

得分: 1

以下函数计算阶乘

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

而这个函数计算最后三位非零数字

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
  • 从结果数字中,提取最多的最后三位数字(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
英文:

The following function calculates the factorial:

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

And this function calculates the last 3 non-zero digits:

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));
}
  • delete trailing zeroes: while the last digit is 0 (dividable by 10, hence i % 10 = 0), divide by 10
  • from the resulting number, extract the (at most) last 3 digits (i % 1000)

Test:

for (int i = 1; i &lt;= 15; i++) {
    BigInteger f = factorial(i);
    System.out.println(i+&quot;! = &quot;+f + &quot; -&gt; &quot; + last3NonzeroDigits(f));
}

Output:

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

答案2

得分: 0

以下是翻译好的内容:

你可以将数字映射到字符串,循环遍历各个数字,找到最后一个位置,其中可以找到最大的三个非零数字,最后可以返回该索引,并将最后的数字打印出来作为你的结果。我已经编写了一点代码,并编写了方法 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 方法,你可以参考下面的 文章。或者你也可以颠倒 for 循环。希望对你有所帮助。

英文:

You can map the number to a string, loop over the digits, find the last index where maximum three non-zero digits can be found and at the end you can return the index and print the last digits as your result. I have coded a little bit and write the method findLastIndex to get the index:

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(&#39;0&#39;)){
            counter++
            zero = false;
        }
        
        if((reversedNum[i].equals(&#39;0&#39;) || counter &gt;= 3) &amp;&amp; !zero){
            return num.length - i - 1
        }
    }
    
    return 0
}

Now you can call the method and print the last non-zero digits:

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

You can test it in the kotlin playground. Mapping in Java should be easy to do. For the reverse method you can have a look at the following article. Or you can inverse the for loop. Hope it helps.

huangapple
  • 本文由 发表于 2020年8月28日 22:25:28
  • 转载请务必保留本文链接:https://go.coder-hub.com/63635716.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定