这是浪费计算阶乘持续这样的,因为你复制在x!
所做的工作,当你做(x+1)!
,(x+2)!
等。
一种方法是维护给定范围内的阶乘列表(例如所有64位无符号阶乘因子),并将其与之进行比较。鉴于因子增长的速度有多快,该列表不会很大。事实上,这里有一个C元程序,实际上为您生成的功能:
#include <stdio.h>
int main (void) {
unsigned long long last = 1ULL, current = 2ULL, mult = 2ULL;
size_t szOut;
puts ("int isFactorial (unsigned long long num) {");
puts (" static const unsigned long long arr[] = {");
szOut = printf (" %lluULL,", last);
while (current/mult == last) {
if (szOut > 50)
szOut = printf ("\n ") - 1;
szOut += printf (" %lluULL,", current);
last = current;
current *= ++mult;
}
puts ("\n };");
puts (" static const size_t len = sizeof (arr)/sizeof (*arr);");
puts (" for (size_t idx = 0; idx < len; idx++)");
puts (" if (arr[idx] == num)");
puts (" return 1;");
puts (" return 0;");
puts ("}");
return 0;
}
当您运行的是,你得到的功能:
int isFactorial (unsigned long long num) {
static const unsigned long long arr[] = {
1ULL, 2ULL, 6ULL, 24ULL, 120ULL, 720ULL, 5040ULL,
40320ULL, 362880ULL, 3628800ULL, 39916800ULL,
479001600ULL, 6227020800ULL, 87178291200ULL,
1307674368000ULL, 20922789888000ULL, 355687428096000ULL,
6402373705728000ULL, 121645100408832000ULL,
2432902008176640000ULL,
};
static const size_t len = sizeof (arr)/sizeof (*arr);
for (size_t idx = 0; idx < len; idx++)
if (arr[idx] == num)
return 1;
return 0;
}
这是相当短的,高效的,甚至64位析因。
如果你是一个纯粹的编程方法(没有查找表)后,您可以使用一个阶乘数是属性:
1 x 2 x 3 x 4 x ... x (n-1) x n
为n
一些价值。
因此,您可以简单地开始将测试编号除以2
,然后3
然后4
等。两件事情之一会发生。
首先,您可能会得到一个非积分结果,在这种情况下,其不是的因子。
其次,您可能以1
从该部门结束,在这种情况下它是的因子。
假设你的部门是不可或缺的,下面的代码将是一个很好的起点:
int isFactorial (unsigned long long num) {
unsigned long long currDiv = 2ULL;
while (num != 1ULL) {
if ((num % currDiv) != 0)
return 0;
num /= currDiv;
currDiv++;
}
return 1;
}
然而,对于效率,最好的选择可能是第一个。将计算成本移至构建阶段,而不是在运行时。如果计算成本与查表相比较显着,则这是一种标准技巧。
你可能甚至通过使用查找表的二进制搜索甚至可以使模式有效,但考虑到其中只有二十个元素,这可能不是必需的。
有知阶乘的数组.... –
我已经尝试过了。对不起,我忘了在提问中提到它。 –
“我试过了。” - 这意味着? –