- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
下面的代码运行完美,但我希望有人向我解释它背后的数学原理。基本上,它是如何工作的?
#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 的最高次幂:
让我们将执行此操作的代码部分提取到一个函数中:
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/
考虑 this link来自 Bit Twiddling Hacks 网站。为了计算尾随位,使用了以下算法: unsigned int v; // 32-bit word input to
我正在开发一个在输出目录中创建多个文件的 makefile。为了创建这些文件,输出目录需要已经存在,否则文件创建失败。 这是一个演示我遇到的问题的最小示例: .PHONY: default defau
我试图让 TextField 的值以尾随对齐方式显示。 如您所见,值 34.3 以前导对齐方式显示。 我确信我遗漏了一些明显的东西,但我不知道是什么。有什么想法吗? @State private va
我想让我的 StackView 在屏幕上居中,并在每边(左和右)添加一个 20 的填充以获得屏幕边距: 但不考虑左边距: 结果如下: 如何处理右边距?对于其他类型的对象(不是 StackView),我
我们在我们的网站上使用漂亮的网址。几年前我有一个外部技术人员添加反向链接。他做得很好,但在一个案例中,他总是添加一个尾随空格字符的链接。 https://www.example.com/item/it
我正在设计一个带前缀的可变长度整数。 Rust 具有计算前导和尾随 1 和 0 的方法:https://doc.rust-lang.org/std/primitive.u64.html#method.
Passing a lambda to the last parameter In Kotlin, there is a convention that if the last parameter o
我需要正则表达式的帮助来从字符串中去除不需要的字符(在 Java 中)。我用 4 个正则表达式解决了这个问题。替换将被多次调用 [peeks: 50+ times/sec] 它并降低性能。但我认为它肯
如果我用 base64 编码一个由七个字符组成的字符串,例如abcdefg 与网站 https://www.base64encode.org/结果是 YWJjZGVmZw==。尾部的“==”字符被填充
尝试在客户端上使用 sprintf 打印出包含缓冲区的 char[]。最后一个字符是“\0”。这是我的服务器代码: char buffer[MAXDATASIZE]; char res[MAXDATA
我在 angular2 项目中遇到问题,我正在生成一个要通过电子邮件发送给用户的 URL。电子邮件中的 URL 需要包含一个特殊 ID,该 ID 在路由器中传递为: { 路径:somepath/:id
我正在尝试删除所有前导和尾随 在使用 PHP 的字符串中。 举个例子 Hello World This is a message... 我想回去 Hello World This is a mes
我有一个 JSON 输出,我想稍微修改一下: JSON={"type":"global", "elements":[ {"type":"car","model":"bmw", "element
继续阅读 ranges-v3 库,我意识到所有关于模板类型有效表达式的检查都有一个尾部 ", 42"表达式,我想知道这样做的目的是什么。例如: namespace concepts { con
我使用的是最新版本的 Xcode (11 Beta 16) 和 macOS (10.15 Beta 6) 我正在尝试创建两个 View 。从第一个 View ,您应该能够通过尾随导航栏项目导航到第二个
我在使用 SwiftUI 时遇到性能问题 List有大量数据。我创建了一个演示应用程序只是为了展示 500_000 String 的问题s 并显示其中一个的尾随 Action ,CPU 将在几秒钟内达
我正在使用 Blue River 的最新 docker 镜像,运行 docker-compose 启动它并在 Mura CMS 中部署一个站点包。 问题是,当我访问 URL 后面没有正斜杠的页面时,我
我是一名优秀的程序员,十分优秀!