這是浪費計算階乘持續這樣的,因爲你複製在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;
}
然而,對於效率,最好的選擇可能是第一個。將計算成本移至構建階段,而不是在運行時。如果計算成本與查表相比較顯着,則這是一種標準技巧。
你可能甚至通過使用查找表的二進制搜索甚至可以使模式有效,但考慮到其中只有二十個元素,這可能不是必需的。
有知階乘的數組.... –
我已經嘗試過了。對不起,我忘了在提問中提到它。 –
「我試過了。」 - 這意味着? –