gpt4 book ai didi

c - 此代码如何从任何基数阶乘中找到尾随零的数量?

转载 作者:太空狗 更新时间:2023-10-29 16:53:14 25 4
gpt4 key购买 nike

下面的代码运行完美,但我希望有人向我解释它背后的数学原理。基本上,它是如何工作的?

#include <stdio.h> 
#include <stdlib.h> /* atoi */

#define min(x, y) (((x) < (y)) ? (x) : (y))

int main(int argc, char* argv[])
{
const int base = 16;
int n,i,j,p,c,noz,k;

n = 7; /* 7! = decimal 5040 or 0x13B0 - 1 trailing zero */
noz = n;
j = base;
/* Why do we start from 2 */
for (i=2; i <= base; i++)
{
if (j % i == 0)
{
p = 0; /* What is p? */
while (j % i== 0)
{
p++;
j /= i;
}
c = 0;
k = n;
/* What is the maths behind this while loop? */
while (k/i > 0)
{
c += k/i;
k /= i;
}
noz = min(noz, c/p);
}
}
printf("%d! has %d trailing zeros\n", n, noz);

return 0;
}

最佳答案

请注意,该问题等同于找到 base 的最高幂,它可以整除 n!

如果基数是素数(我们称之为p),我们可以使用theorem from number theory计算除以 n!p 的最高次幂:

enter image description here

让我们将执行此操作的代码部分提取到一个函数中:

int maximum_power_of_p_in_fac(int p, int n) {
int mu = 0;
while (n/p > 0) {
mu += n/p;
n /= p;
}
return mu;
}

现在如果 base 是素数会怎样?假设我们有 base = pq。那么如果 μp 的最高次幂,它将 n!r = floor(μ/q) , 我们有

(p^q)^r = p^(qr) divides p^μ divides n!

(p^q)^(r+1) = p^(q(r+1)) >= p^(μ+1) does not divide n!

所以 r 是 n! 中 p^q 的最大幂。让我们也为此编写一个函数:

int maximum_power_of_pq_in_fac(int p, int q, int n) {
return maximum_power_of_p_in_fac(p, n) / q;
}

如果 base 是一般数字呢?假设

base = p1q1 p2q2 ... pmqm

(这是 base 的唯一质因数分解)。然后我们只解决所有 piqi 的问题,并取其中的最小值:

int maximum_power_of_base_in_fac(int base, int n) {
int res = infinity;
for every factor p^q in the prime factorization in base:
res = min(res, maximum_power_of_pq_in_fac(p,q,n));
return res;
}

如何分解基数?好吧,我们可以像您的示例代码一样使用试验除法。我们首先检查 2 是否是质因数。如果是,我们计算 maximum_power_of_pq_in_fac 并将 base 除以 2,直到它不能再被 2 整除。然后我们继续下一个候选因子:

void factorize(int base) {
for (int p = 2; p <= base; ++p) {
if (base % p == 0) { // if base is divisible by p, p is a prime factor
int q = 0;
while (base % p == 0) { // compute q and get rid of all the p factors
q++;
base /= p;
}
// do something with factor p^q
}
// proceed with next candidate divisor
}
}

仔细检查代码,您会发现它包含了上述所有元素,只是放在一个循环中,这有点令人困惑。

更新:如果您有兴趣,您提供的算法具有复杂性 O(base * log n)。通过稍微调整质因数分解例程,您可以轻松地使其O(sqrt(base) * log n):

void factorize(int base) {
for (int p = 2; p*p <= base; ++p) { // only check prime factors up to sqrt(base)
// ... same as before
}
if (base) {
// there is exactly one prime factor > sqrt(base).
// It certainly has multiplicity 1.

// process prime factor base^1
}
}

当然,如果您想进一步加快速度,您可以使用任何其他更复杂的质因数分解算法。

关于c - 此代码如何从任何基数阶乘中找到尾随零的数量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23202489/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com