迭代阶乘函数:
function factorial($number) {
$result = 1;
while ($number > 0) {
$result *= $number;
$number--;
}
return $result;
}
递归阶乘函数:
function factorial($number) {
if ($number < 2) {
return 1;
} else {
return ($number * factorial($number-1));
}
}
我必须开发一个函数来计算PHP程序中的阶乘。我发现我可以通过以上两种方式做到这一点。
我不知道哪种方法更好,为什么?
行业标准是什么?
如何在上述两种方法之间选择一种?
确定哪个更好的条件是什么?
我知道有很多问题,但是由于我是PHP新手,所以希望有人能帮助我。
鉴于此,实际上我正在使用的功能不仅仅是析因。它也有其他一些行可以执行其他任务。为了简化起见,我们假设这是两个函数。因此,任何人都可以无缘无故地理解我的问题而不是使其复杂化。
我基本上指的是PHP中的递归与迭代。
如有疑问,请不要在PHP中使用递归:)
如果您在stackoverflow.com/questions/6171807/中看到评论,则应该得到答案。
没有"标准"。 某些程序可以用递归形式编写得更加优雅。 有些不能。 递归的一个缺点是,它为每个函数调用生成一个堆栈框架。 得到足够的那些,就会出现堆栈溢出。
行业标准通常会使用内置功能。 gmp_fact(n)
@Dasum:这个问题与哪个特定的PHP 5版本相关?
@hakre我认为PHP5支持递归和迭代。
感谢您的链接和信息
@Dasun:只要您通常询问有关PHP编程语言的信息,只需将其标记为PHP。 如果您担心某个版本的特定差异,请将版本号添加到标记中,例如PHP-5.1。
我在这里写了一个额外的细节stackoverflow.com/questions/660337/recursion-vs-loops/
PHP是一种特例。使用迭代解决方案,您将使用更少的内存。而且,PHP中的函数调用成本很高,因此最好避免使用函数调用。
PHP会(在我的系统上)尝试查找100,000的阶乘分解故障,但是迭代解决方案没有问题。但是,它们实际上都是即时执行的。
当然,小得多的阶乘是INF,但这也可以应用于增长慢得多的函数。
如果我们不是在谈论PHP或其他脚本语言,那么就没有标准。很高兴知道两种方法都可以做到。我将选择导致最干净代码的代码。
What I don't know is which method is better to used and why?
经验法则:如果可以迭代编写,请使用它。这是因为函数调用和递归在PHP中会带来一些损失。另外,PHP本身没有递归保护,您可能会冒大量内存耗尽的风险。
What's the industry standard?
据我所知,尚无用于计算阶乘的行业标准。总的来说,行业标准不涉及这些细节。如果他们这样做,那就太好了。
How can I select one of the methods between above two?
独立于函数的真实性质,您只需通过在输入域上运行这些函数并对其进行基准测试,就可以得出一个结论,即哪个更好。
What's the condition to determine which one is better?
记忆和时间是重要因素。您应该尝试实现低内存消耗和短执行时间。这并非总是可能的,在这种情况下,您需要妥协其中之一。
就是说,我会选择一个迭代的解决方案。
顺便说一句,如果PHP要实现尾部递归优化,则可以这样编写阶乘函数:
function fact($n, $r = 1)
{
if ($n < 2) {
return $r;
} else {
return fact($n - 1, $r * $n);
}
}
@NullUserException这里,递归是函数的最后一条语句,因此可以安全地替换堆栈。
在执行之前,您神奇地将$number乘以递归调用的结果吗?
据我所知,第一个要比递归好。因为这会导致大量系统开销,有时还会停止脚本。
我创建了一个脚本来测试这些方法中哪种更快。
$f = 12; //calculate factorial of this number
$n = 10000000; //the number of times the process is repeated
//factorial using iterative function
function f1($a) {
$r = $a;
for($i=$a-1; $i >= 2; $i--)
$r *= $i;
return $r;
}
//factorial using recursive function
function f2($a) {
return $a < 2 ? 1 : $a * f2($a - 1);
}
echo"
";
$start = microtime(true);
for($i=0; $i < $n; $i++)
$x = f1($f);
echo"f1():" . ((microtime(true) - $start) * 1000) ." ms
";
$start = microtime(true);
for($i=0; $i < $n; $i++)
$x = f2($f);
echo"f2():" . ((microtime(true) - $start) * 1000) ." ms
";
结果:
f1(): 6 648 ms
f2(): 12 415 ms
除了递归使用更多内存这一事实外,它比迭代慢了约1.87倍。在PHP 7上测试。