返回顶部
首页 > 资讯 > 后端开发 > PHP编程 >php如何实现n的阶乘
  • 633
分享到

php如何实现n的阶乘

2023-06-15 08:06:56 633人浏览 泡泡鱼
摘要

这篇文章主要介绍PHP如何实现n的阶乘,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!php实现n的阶乘的方法:1、通过普通递归实现,代码如“function fact(int $n): int{...}”;2、通过普

这篇文章主要介绍PHP如何实现n的阶乘,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!

php实现n的阶乘的方法:1、通过普通递归实现,代码如“function fact(int $n): int{...}”;2、通过普通循环实现,代码如“while ($num <= $n) {$result = $result...}”。

本文操作环境:windows10系统、PHP 7.2.15版,DELL G3电脑

php怎么实现n的阶乘?

据本人了解,阶乘的实现方法一般可以分为三种,通常意义下的递归和循环各算一种,还有一大类通过一些巧妙的数学方法减少运算次数(尤其是乘法运算次数),进而优化计算效率。

如果要考虑到高精度、大整数的阶乘,对于 PHP 语言而言,情况会更复杂一些,比如使用 BCMath 扩展提供的一些方法时,显式的数字与字符串转换操作比较频繁。

本文在只考虑 n 为整数的情况下,分别尝试实现上述的几种情况,每种情况给出可用的代码示例,并在文末附上几种方法的综合对比情况。

普通递归实现

首先是普通递归实现,根据递归的通用公式 fact(n) = n * fact(n-1) 很容易写出阶乘的计算代码。普通递归实现的优点在于代码比较简洁,和通用公式一样的过程使得代码容易理解。缺点则在于由于需要频繁地调用自身,需要大量的入栈出栈操作,整体的计算效率不高(见文末表格)。

function fact(int $n): int{    if ($n == 0) {        return 1;    }    return $n * fact($n - 1);}

普通循环实现

普通循环实现有些「动态规划」的味道,但由于中间态变量使用频率低,不需要额外存储空间,所以要比一般的动态规划算法简单。普通递归方法是自顶向下(由 n 到 1)的计算过程,而普通循环是自底向上进行计算。

因此相对而言,代码没有上述方法直观,但由于少了频繁的入栈出栈过程,计算效率会高一些(见文末表格)。

function fact(int $n): int{    $result = 1;    $num = 1;    while ($num <= $n) {        $result = $result * $num;        $num = $num + 1;    }    return $result;}

自行实现的大整数阶乘

由于 PHP 中 int 类型的范围限制,上述两种方法最多只能精确计算到 20 的阶乘。如果只是考虑到 20 的阶乘的情况,那么用查表法实现会更快:事先计算好 0-20 的阶乘并存储到一个数组中,需要用时查询一次便可。

为了能够适应大数的阶乘,得到精确的计算结果,本文基于「普通循环方法」进行改进,使用数组存储计算结果中的每一位(由低到高位),通过相乘进位的方式依次计算每一位的结果。

不言而喻,本方法的优点在于可以适用于高精度的大数阶乘场合,缺点就是对于小数阶乘而言,计算过程复杂且速度慢。

function fact(int $n): array{    $result = [1];    $num = 1;    while ($num <= $n) {        $carry = 0;        for ($index = 0; $index < count($result); $index++) {            $tmp = $result[$index] * $num + $carry;            $result[$index] = $tmp % 10;            $carry = floor($tmp / 10);        }        while ($carry > 0) {            $result[] = $carry % 10;            $carry = floor($carry / 10);        }        $num = $num + 1;    }    return $result;}

BCMath 扩展方法

BCMath 是 PHP 的一个数学扩展,用于处理字符串表示的数字(任意大小和精度)的数值计算。由于是使用 C 语言实现的扩展,计算速度会比上述自行实现的快。

在本人的笔记本上,同样是计算 2000 的阶乘,自行实现的需要平均 0.5-0.6 秒,使用 BCMath 耗时 0.18-0.19 秒。该方法的缺点主要在于需要安装相应的扩展,属于非代码层面的改动,对于环境管理升级不便的应用而言,可实践性有待商榷。

function fact(int $n): string{    $result = '1';    $num = '1';    while ($num <= $n) {        $result = bcmul($result, $num);        $num = bcadd($num, '1');    }    return $result;}

优化算法

在本文开头有提到,优化算法尝试尽可能地减少运算次数(尤其是乘法的运算次数)来实现快速阶乘。考虑到对于小整数阶乘而言,最快的算法应该是查表法,时间复杂度为 O(1),所以本小节主要针对大整数的精确阶乘进行讨论和测试

据了解,目前阶乘优化比较常见的是通过 n! = C(n, n/2) * (n/2)! * (n/2)! 式子进行复杂度优化,而该式子中的亮点主要在于 C(n, n/2) 的优化。考虑到大整数情况下,PHP 语言实现 C(n, n/2) 的效率不高,而且实现的代码可读性比较差(频繁的数字与字符串的显式转换),所以本文用的是另外一种比较巧妙的方法。

乘法的计算速度通常要低于加减法运算,通过减少乘法的运算次数可以提高整体运算速度。通过数学归纳可以发现,对于 n 的阶乘,可以依次求出比 (n/2)^2 小 1、1+3、1+3+5... 的数值,再依次相乘得到目标值。

该算法的优点在于计算速度较快,而缺点就是实现过程不直观、不易理解。经测试,以下代码计算 2000 的阶乘平均时间为 0.11 秒,大约是普通循环方法的一半耗时。

除了这种方法优化,也有看到其它的类似的思路,比如对 1...n 中的数反复检验是否被 2 整除,记录下被 2 整除的次数 x,并尝试归纳出共同的奇数相乘式,最后乘以 2^x 得到结果。

function fact(int $n): string{    $middleSquare = pow(floor($n / 2), 2);    $result = $n & 1 == 1 ? 2 * $middleSquare * $n : 2 * $middleSquare;    $result = (string)$result;    for ($num = 1; $num < $n - 2; $num = $num + 2) {        $middleSquare = $middleSquare - $num;        $result = bcmul($result, (string)$middleSquare);    }    return $result;}

综合对比

本文中提到的方法是按照由劣到优的顺序,因此,下列表格中每一行中提到优劣势,主要是和其上一两种方法对比。

表格中「测试耗时」一列的测试环境为个人笔记本,硬件配置为 Dell/i5-8250U/16GB RAM/256GB SSD Disk,软件配置为 Win 10/PHP 7.2.15。

php如何实现n的阶乘

以上是“php如何实现n的阶乘”这篇文章的所有内容,感谢各位的阅读!希望分享的内容对大家有帮助,更多相关知识,欢迎关注编程网PHP编程频道!

--结束END--

本文标题: php如何实现n的阶乘

本文链接: https://lsjlt.com/news/278957.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • php如何实现n的阶乘
    这篇文章主要介绍php如何实现n的阶乘,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!php实现n的阶乘的方法:1、通过普通递归实现,代码如“function fact(int $n): int{...}”;2、通过普...
    99+
    2023-06-15
  • php中如何实现n阶乘
    这篇文章主要介绍了php中如何实现n阶乘,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。1、普通递归实现首先是普通递归实现,根据递归的通用公式 fact(n) = n * fa...
    99+
    2023-06-15
  • php如何用循环实现n的阶乘
    这篇文章主要介绍“php如何用循环实现n的阶乘”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“php如何用循环实现n的阶乘”文章能帮助大家解决问题。php用循环实现n的阶乘的方法:1、新建一个php示...
    99+
    2023-07-04
  • php怎么用循环实现n的阶乘
    php用循环实现n的阶乘的方法:1、新建一个php示例文件;2、添加php的界定符;3、声明PHP与浏览器交互的文件类型和编码;4、定义一个函数compute(),并且添加参数$num;5、使用for语句计算参数$num的阶乘;6、使用re...
    99+
    2023-05-14
    阶乘 循环 php
  • python 如何求N的阶乘
    目录求N的阶乘实现阶乘的三种解法解法一:循环解法二:递归解法三:数组①i=1②i=2③i=3④i=4⑤i=5求N的阶乘 本题要求编写程序,计算N的阶乘。 输入格式: 输入在一行中给出...
    99+
    2024-04-02
  • PHP如何实现求阶乘
    小编给大家分享一下PHP如何实现求阶乘,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧! function fa...
    99+
    2024-04-02
  • 怎么使用javascript实现n的阶乘
    这篇文章主要介绍“怎么使用javascript实现n的阶乘”,在日常操作中,相信很多人在怎么使用javascript实现n的阶乘问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”...
    99+
    2024-04-02
  • Java实现递归计算n的阶乘
    本文实例为大家分享了Java实现递归计算n的阶乘的具体代码,供大家参考,具体内容如下 问题描述 利用递归的思想实现阶乘的计算,以 n!为例 (一)、n的范围 1.n<0:n!无...
    99+
    2024-04-02
  • Java递归简单实现n的阶乘
    目录1.递归的基本概念2.递归的重要规则3.利用递归实现n的阶乘1.递归的基本概念 在说什么是递归之前,我想大家定见过这个表情包吧 什么是递归: 程序调用自身的编程技巧称为递归( ...
    99+
    2024-04-02
  • JavaScript如何用for求n的阶乘
    这篇文章主要介绍了JavaScript如何用for求n的阶乘,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。 用f...
    99+
    2024-04-02
  • Python怎么实现数学阶乘n!
    这篇文章主要介绍了Python怎么实现数学阶乘n!的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Python怎么实现数学阶乘n!文章都会有所收获,下面我们一起来看看吧。python实现阶乘-基础版本什么是阶乘呢...
    99+
    2023-07-05
  • 详解Python如何巧妙实现数学阶乘n!
    目录python实现阶乘-基础版本方式1-累乘方式2-使用递归函数方式3-第三方库functools的reduce函数python实现阶乘累加求和-进阶版方式1-累乘+sum方式2-...
    99+
    2023-03-19
    Python计算数学阶乘n! Python数学阶乘n! Python阶乘
  • php如何实现1到10的阶乘
    这篇“php如何实现1到10的阶乘”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“php如何实现1到10的阶乘”文章吧。php...
    99+
    2023-07-05
  • 如何在Python 中计算N的阶乘
    本篇文章为大家展示了如何在Python 中计算N的阶乘,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。1)使用循环计算阶乘def frac(n):  r =&n...
    99+
    2023-06-09
  • c语言如何计算n的阶乘
    本篇内容主要讲解“c语言如何计算n的阶乘”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“c语言如何计算n的阶乘”吧!c语言计算n的阶乘的方法:1、通过for循环计算阶乘,代码如“for (i = ...
    99+
    2023-07-04
  • python怎么求N的阶乘
    今天小编给大家分享一下python怎么求N的阶乘的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。求N的阶乘本题要求编写程序,计...
    99+
    2023-06-30
  • 五种C程序计算阶乘方法 c语言实现1到n的阶乘1*2*3*.....*n的累乘计算,使用不同方法实现,五种计算阶乘的方法
    题目: 题目分析:        首先要清楚阶乘定义,所谓 n 的阶乘,就是从 1 开始乘以比前一个数大 1 的数,一直乘到 n,用公式表示就是:1×2×3×4×…×(n-2)×(n-1)×n=n! 具体的操作: 利用循环解决问题,设循环...
    99+
    2023-10-21
    c++ c语言 python java c#
  • c语言怎么求n的阶乘
    C语言可以使用循环来求n的阶乘。以下是一种常见的求阶乘的方法:```c#include int main() {int n, i;u...
    99+
    2023-08-09
    c语言
  • c语言n的阶乘怎么写
    在 c 语言中,计算 n 的阶乘有两种方法:递归方法:编写一个函数,函数调用自身,阶乘等于 n 乘以 n-1 的阶乘。循环方法:使用循环变量逐步计算阶乘,阶乘等于 1 乘以 2,再乘以 ...
    99+
    2024-05-23
    c语言 堆栈溢出
  • php怎么实现阶乘算法
    实现步骤:1、定义一个变量并赋值1,用于储存阶乘结果,语法“$cj=1;”;2、使用for语句循环遍历“1~n”范围的数,求n的阶乘,语法“for ($i = 1; $i <= $n; $i++) {//循环体代码}”;3、在循环体中...
    99+
    2022-08-11
    php
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作