再谈循环&迭代&回溯&递归&递推这些基本概念

循环:不断重复进行某一运算、操作。

迭代:不断对前一旧值运算得到新值直到达到精度。一般用于得到近似目标值,反复循环同一运算式(函数),并且总是把前一 次运算结果反代会运算式进行下一次运算

递推:从初值出发反复进行某一运算得到所需结果。-----从已知到未知,从小到达(比如每年长高9cm,20年180,30后270)

回溯:递归时经历的一个过程。

递归:从所需结果出发不断回溯前一运算直到回到初值再递推得到所需结果----从未知到已知,从大到小,再从小到大(你想进bat,那么编程就的牛逼,就得卸载玩者农药,努力学习)。递归(Recursion)是从归纳法(Induction)衍生出来的

一个运算(操作),可以通过不断调用本身的运算形式,往往需要通过前一次的结果来得到当前运算的结果,因而,程序运行时,总是先一次次地「回溯」前一次的结果(回溯过程中这些结果是未知的,直到回溯到初值令回溯终止,再层层递推回来得到当前要求的值)

一个完整的递归应该有下面三个条件,否则就是不合格的递归

  1. 明确递归的终止方法(一个递归必须有他递推到头的界定,否则将会是无限递归 )

  2. 明确的终止时处理方法

  3. 重复调用自身并缩小问题规模

死循环不会栈溢出而无限递归会出现栈溢出情况,详情推荐阅读:《递归-程序之美,及其与循环的区别》,但实际上业务模型几乎不会遇到。

kidneyball知乎回答总结会精辟

在有循环的语言里,有的人认为尾递归优化除了炫技之外是完全无用的。其实不然,尾递归写法在我看来有以下好处

  1. 强迫你把循环写成单独的函数。这又有什么好处呢?这会影响你的编程风格,习惯使用尾递归之后,你的写出一个几百行大函数的机率会小得多。

  2. 保证没有副作用,统一使用不可变数据。在循环里,循环变量就是一个可变数据。作为人肉开发者,如果想保证自己的某段程序没有副作用,最好的做法就是根本不要写任何带副作用的东西,这样代码审查时一眼看过去就能知道有没有副作用。至于避免副作用有什么好处,这又可以写一篇文章,这里就不展开了。

  3. 转换成惰性序列时比较好看。在某些语言里,尾递归形式基本上只要去掉循环变量(变成无限递归), 把初始状态作为首元素,就是一个能直接拿来用的惰性序列。

“递归”是一种思路,这种思路的特点是:我不关注问题本身,我只关注这个问题如何可以用一种可重复的方式分解为一些规模更小的子问题,以及这些子问题与原问题的关系。再加上当问题的规模足够小的时候,存在一个简单直接的解法。

递推和递归还是迷糊,show code

//递归求解
function fib(n){
    return n <2?1:fib(n-1) + fib(n-2);
}
//递推求解
function fib(n){
    let start=0;
    let fn=1;
    for (let i=0;i<n;i++) {
        let t=fn;
        fn=fn+start;
        start=t;
    }
    return fn;
}

不难看出,

程序的一般写法就好比是数列的通项公式。
程序的递归写法就好比是数列的递推公式。

原文链接:再谈循环&迭代&回溯&递归&递推这些基本概念 - 模型设计,领域设计,软件设计, - 周陆军的个人网站,不定时更新,文有不妥之处,请留言告知,多谢(再谈系列多为总结性文章(搬砖凑))。

推荐文章:

程序员们,以后再也别问我递归的问题了

递归-程序之美,及其与循环的区别

上一篇:UVa 11210 - Chinese Mahjong


下一篇:区别CALL SCREEN/SET SCREEN/LEAVE TO SCREEN