100阶乘中有多少零

时间:2019-05-21 10:58:54

标签: math

我有一个家庭作业,在n阶乘中计数为零。我该怎么办? 我只找到计数阶乘

的方法
FROM java:8
EXPOSE 8082
ADD /build/libs/tsi-csrportal-gui-2.0-SNAPSHOT.jar dockerDemoCsrportal.jar
ENTRYPOINT ["java", "-DTSI_APP_NAME=csrportal", "-DTSI_ENV=test", "-Dtsi.log.console", "-jar", "dockerDemoCsrportal.jar"]

4 个答案:

答案 0 :(得分:3)

n!中零的总数由整数序列在线百科全书中的序列A027869给出。似乎没有办法计算n!中的n!中的零总数并计算零的数目。有了一个大的int库,这很容易。一个简单的Python示例:

import math

def zeros(n): return str(math.factorial(n)).count('0')

例如,zeros(100)的值为30。对于较大的n,您可能希望跳过相对昂贵的转换为字符串,并通过反复除以10来算术得到0计数。

您已经注意到,计算尾随零的数量要容易得多。在Python中,您的代码本质上是:

def trailing_zeros(n):
    count = 0
    p = 5
    while p <= n:
        count += n//p
        p *= 5
    return count

作为一种估算零总数的启发式方法,您可以先计算尾随零的数目,从n!中的位数中减去该数目,再从该差中减去另外的2(因为n!的第一个数字或结尾的零之前的最后一个数字是非结尾零的候选位置),并猜测这些数字中的1/10实际上将为零。您可以使用Stirling's formula来估算n!中的位数:

def num_digits(n):
    #uses Striling's formula to estimate the number of digits in n!
    #this formula, known as, Kamenetsky's formula, gives the exact count below 5*10^7
    if n == 0:
        return 1
    else:
        return math.ceil(math.log10(2*math.pi*n)/2 + n *(math.log10(n/math.e)))

因此:

def est_zeros(n):
    #first compute the number of candidate postions for non-trailing zerpos:
    internal_digits = max(0,num_digits(n) - trailing_zeros(n) - 2)
    return trailing_zeros(n) + internal_digits//10 

例如est_zeros(100)的计算结果为37,这不是很好,但是没有理由认为此估计比渐近更好(尽管证明渐近正确将是非常困难的,我实际上不知道是否如此)。对于更大的数字,似乎给出了合理的结果。例如zeros(10000) == 5803est_zeros == 5814

答案 1 :(得分:0)

那呢。

count = 0
s = str(fact)
for i in s:
    if i=="0":
        count +=1
print(count)

答案 2 :(得分:0)

100!是一个很大的数字:

100! = 93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000

更准确地说,它需要525位,并且没有某种形式的bigint数学就无法计算。

但是尾随零点可以在普通整数上计算:

这个想法是限制结果仍然适合您的数据类型。因此,在每次迭代测试之后,结果是否都可以被10整除。如果是,则将您的零计数器递增,并在可能的情况下将结果除以10。除素数除以10以外的素数之外,其他素数也相同:2,5(但不增加零计数器)。这样,您将获得较小的子结果和尾随零的数量。

因此,如果对2,5中的所有乘数进行n!分解,则两个指数的最小值2,5将是尾随零的数目,因为每对产生一个零数字({ {1}})。如果您意识到2*5 = 10的指数总是小于或等于5的指数,足以进行2的因式分解(就像在更新的代码中一样)。

5

有结果:

int fact_trailing_zeros(int n)
    {
    int i,n5;
    for (n5=0,i=5;n>=i;i*=5) n5+=n/i;
    return n5;
    }

但是Trailing zeors of n! 10! : 2 100! : 24 1000! : 249 10000! : 2499 100000! : 24999 1000000! : 249998 10000000! : 2499999 100000000! : 24999999 [ 0.937 ms] 也包含非尾随零,并且要计算这些,我发现除了在100!数学上计算真实事物外,别无其他方法……但是意味着没有像尾随零这样的解决方法...

如果有帮助,这里可以计算bigint以下的计算阶乘,因此您可以检查结果:

如果128!的值必须足够小,则可以使用 LUT 将所有阶乘以字符串或 BCD 的形式保存到上限,然后仅计算从那里开始为零...或者甚至只是最终结果为 LUT ...

答案 3 :(得分:0)

这里有一些错误的代码,但是可以。您只需要使用TrailingZeros()

    public static int TrailingZeros(int n)
    {
        var fac = Factorial(n);
        var num = SplitNumber(fac);
        Array.Reverse(num);
        int i = 0;
        int res = 0;

        while (num[i] == 0)
        {
            if (num[i] == 0)
            {
                res++;
            }
            i++;
        }
        return res;
    }
    public static BigInteger Factorial(int number)
    {
        BigInteger factorial = 1;   // значение факториала

        for (int i = 2; i <= number; i++) 
        {
            factorial = factorial * i;
        }
        return factorial;
    }

    
    public static int[] SplitNumber(BigInteger number)
    {
        var result = new int[0];
        int count = 0;

        while (number > 0)
        {
            Array.Resize(ref result, count + 1);
            result[count] = (int)(number % 10);
            number = number / 10;
            count++;
        }
        Array.Reverse(result);
        return result;
    }