阶乘的运算法则的运行(前n项阶乘的和公式)

先从熟稔的数学着手起步。1.线型迭代与递归LinearRecursionandIteration我们从“阶乘”开始。n!=n*(n-1)*(n-2)….3*2*1计算“阶乘”的方法有很多,最直觉的一种解法(从n逐次递减)n!=n⋅(

先从熟稔的数学着手起步。

1.线型迭代与递归 Linear Recursion and Iteration

我们从“阶乘”开始。

n! = n *(n-1)*(n-2)....3*2*1

计算“阶乘”的方法有很多,最直觉的一种解法(从n逐次递减)

n!=n⋅[(n−1)⋅(n−2)⋯3⋅2⋅1]=n⋅(n−1)!

直接用function表达为:

> function factorial(n) {
... return n === 1
... ? 1
... : n * factorial(n-1);
... }
undefined
> factorial(6)
720

绘制函数执行的Shape:

A linear recursive process for computing 6!.

接下来,我们从另外一个视角审视。从1开始,逐次乘到n:

product <-- counter * product
counter <-- counter + 1

当counter超过n时,输出product结果。

function factorial(n) {
return fact_iter(1, 1, n);
}
function fact_iter(product, counter, max_count) {
return counter > max_count
? product
: fact_iter(counter * product,
counter + 1,
max_count);
}

factorial(5);
# 最终的结果放在前面

同样可视化其执行过程如下:

A linear iterative process for computing 6!.

分析第一种递归结构,执行结构先expansion再constraction。expansion过程建立在层层的deferre-operatioin之上;而constraction过程发生于运算的实际执行中,此种类型的 deferred operations称之为递归a recursive process。

于此相反,第二个函数没有grow和shrink的过程。在每一步中,都对n追踪记录,即product, counter, and max-count。该过程称之为 a linear iterative process.

二者的区别在于,interactive-case,所有的state信息都保存在每一个过程中;而在recursive-case中,编译器维护着hidden-information。

在tail-recursion机制之下,iterative-recursion将会执行为iteration-process。

2.树状递归

第二种“演变模式”是“树状递归”,以Fibonacci数列为例:

0,1,1,2,3,5,8,13,21,…

Fibonacci数列有如下定义:

Fibonacci数列

简单粗暴的将定义实现出来:

function fib(n) {
return n === 0
? 0
: n === 1
? 1
: fib(n - 1) + fib(n - 2);
}

fib(6);

此函数在时间线里演变呈现“树状结构”:

The tree-recursive process generated in computing (fib 5) fib(5)

然而该解决方案的运行效率极低,从图中可知,fib(1), fib(2), fib(3)重复计算。

颇为值得一提的是,Fib(n)的值无限趋近于ϕn/√5。其中 ϕ为“黄金比例”:

ϕ2=ϕ+1

至此,已知函数的“发展演变模式”为树状结构。下一步,如何判断此函数动作是一部“臭棋”还是一步“好棋”呢?答案是从“时间复杂度”和“空间复杂度”两方面着手分析。

于是,我们看到 fib(n)函数在“时间复杂度”上,指数级增长;而另外一方面,”空间复杂度”则“线性增长”。一言以蔽之,树状递归执行的总步数,取决于总的节点数量;而所需的空间则与生成树的最大深度成正比。

作为对比,尝试用iterative的方法计算Fibonacci。须用到一对数a和b,并初始化Fib(1)=1 and Fib(0)=0,反复应用以下转换:

a <--- a + b
b <--- a

a与b的数值最终将分别对应Fib(n+1) and Fib(n)。

function fib(n) {
return fib_iter(1, 0, n);
}
function fib_iter(a, b, count) {
return count === 0
? b
: fib_iter(a + b, a, count - 1);
}

更加符合直觉的表达方式是:

function fib(n) {
return fib_iter(1, 0, n);
}
function fib_iter(next, current, count) {
return count === 0
? current
: fib_iter(next + current, next, count - 1);
}

这第二种解法就是“线型迭代”。

对比以上两种解法。Tree-Recursion的解法更加符合直觉,有助于在初步阶段,梳理清楚脉络;而第二种Linear-Recursion的解法则需要较多的观察,注意到计算过程需要三个状态变量。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,请发送邮件至 55@qq.com 举报,一经查实,本站将立刻删除。转转请注明出处:https://www.szhjjp.com/n/18166.html

(0)
nan
上一篇 2021-08-28
下一篇 2021-08-28

相关推荐

  • asp后台用什么软件做(asp网站用什么软件)

    asp后台用什么软件做,asp网站用什么软件内容导航:运行ASP程序需要什么软件做后台管理开发需要哪些工具这些分别用来做什么做网站后台开发用什么软件好ASPnet用什么编程软件编写比较好一、运行ASP程序需要什么软件做后台管理做ASP程序需要ASP的服务器,windows98的是用安装光盘上的ad

    2022-05-10
    0
  • 图床服务器如何选择配置

    选择图床服务器配置时,主要考虑以下几个方面:存储空间:根据预计的图片存储量和增长速度,选择适合的存储空间容量。一般建议选择大容量的存储空间,以满足未来业务扩展的需求。带宽和流量:考虑用户访问量和图片加载速度需求,选择合适的带宽和流量配置。高带宽和流量配置能够保证用户访问速度和稳定性。数据备份和恢复:选择支持数据备份和恢复功能的图床服务器,以保证数据的安全性和可靠性。服务器性能:根据预计的访问量和图

    2024-04-12
    0
  • CentOS中如何设置定时任务

    在 CentOS 中,可以使用 crontab 命令来设置定时任务。以下是设置定时任务的步骤:使用以下命令打开 crontab 编辑器:crontab -e编辑 crontab 文件,按照以下格式添加定时任务:* * * * * command其中,第一列代表分钟,第二列代表小时,第三列代表日期,第四列代表月份,第五列代表星期,最后一列是要执行的命令。例如,下面是一个每天凌晨 1 点执行一个 s

    2024-04-01
    0
  • 如何保护域名(域名怎么保护)

    如何保护域名,域名怎么保护内容导航:域名保护是什么怎么做域名保护企业如何保护域名什么是域名保护企业如何做好域名保护一、域名保护是什么怎么做域名保护域名保护是指注册品牌域名以及与品牌相关的域名,防止被他人抢注,或被他人仿冒,做一些仿冒网站,以防品牌声誉以及流量的损失。想国内做了域名品牌保护的就有阿里、诺思罗普、施乐、惠普、IBM、苹果等公司就有做域名品牌保护,且早已成为域名保

    2022-05-06
    0
  • 网站后台如何修改参数(网页参数修改)

    网站后台如何修改参数,网页参数修改 内容导航: 网优中后台修改的参数 网站后台进去如何修改网站内容 网站后台修改友情链接不成功 怎样进入后台修改网站资料 一、网优中后台修改的参数 …

    2022-05-18
    0
  • 小程序如何进行热修复

    小程序的热修复可以通过以下步骤进行:确定需要修复的问题:首先要确定哪些问题需要进行热修复,可以通过用户反馈、日志监控等方式来识别需要修复的问题。制定修复方案:针对需要修复的问题,制定相应的修复方案,包括修改代码、资源替换、配置调整等。打包修复补丁:将修复方案打包成一个补丁文件,可以包括需要替换的代码文件、资源文件等。下发补丁:将补丁文件上传至服务器,并通过小程序的动态加载机制在用户打开小程序时动态

    2024-04-17
    0

发表回复

登录后才能评论