7.15-7.20 汉诺塔递归算法和项目中遇到的$apply()问题

IE下有乱码会使取值异常

1.IE不能识别乱码,即使是IE11.会导致取值函数异常 但是chrome下正常
在这里插入图片描述

2.汉诺塔的递归问题

底下有个回答的非常好

先帮着大家了解一下递归函数的一般形式,这样有利于解决本题和其他的递归问题。

首先,计算机计算递归的方式是,计算递归函数func(n)时发现要先计算func(n-1),计算func(n-1)时需要先计算func(n-2)…以此类推,最后在计算func(1)的时候,计算机终于得到了一个答案。然后计算机再把func(1)得到的答案带入到func(2)中,得到func(2)结果带入func(3)中,以此类推,不断地带入最后得到func(n)的结果。那么func(1)的那个答案,就是递归的基础。

其次,再来看看一般形式:

def func(n):

if n == 1:  #也有可能是n==0,具体问题具体分析

    return xxx xxx xxx

else:

    return yyy func(n-1) yyy  #也有可能用到func(n-2)甚至更多,具体问题具体分析

上面这个一般形式由三部分组成:

1、return xxx xxx xxx 这里是递归的基础。计算机终于在func(1)时得到了一个答案。也就是func(1) = xxx xxx xxx

2、return yyy func(n-1) yyy 这里是递归的规律。表明func(n)和func(n-1)的关系,如何操纵func(n-1)得到func(n)。也就是func(n) = yyy func(n-1) yyy

3、通过if else 分支语句区分什么是递归的基础,什么是递归的规律

有了这个一般形式,现在就可以看看如何把老师的问题套入到这个一般形式中。

1、先设定这个递归函数 def move(n, a, b, c),n是汉诺塔上盘子的数量。特别需要注意,a表面上看是代表第一个柱子,但同时,a所在的是第二个参数位置,这个位置的参数表示的是“起始的柱子”。b表示第二个柱子,但这第三个参数位置其实表示的是“辅助的柱子”。c表示第三个柱子,但这第四个参数表示的是最终要挪动到的“终点柱子”。

那么move(n, a, b, c)的意思是,把“起始柱子“上n个圆盘,通过”辅助柱子“,挪动到最终的”终点柱子”上。因为最开始,所有的圆盘都在a柱子上,所以才把a写在了第二个参数起始柱子的位置,b是辅助的柱子,所以写在第三个参数位置。c是终点柱子,所以写在最后的参数位置上。如果给你的汉诺塔,所有的圆盘都在中间那个b柱子上,要通过a柱子的帮助,挪动到c柱子上的话,函数就要写成 move(n, b, a, c) 了。

2、这个递归问题的基础是什么:基础是,如果汉诺塔上只有一个盘子。也就是if n==1 的时候程序应该做什么。由于本问题是输出搬运过程,而不是得到一个返回值,所以不用写return,直接写成 if n == 1: print(a ‘–>’ c) 它表示,当只有一个圆盘时,那就直接把这个圆盘从”起始柱子“搬运到”终点柱子“,也就是把在a上的圆盘,要搬到c上。

3、这个递归问题的规律是什么:思考下n个圆盘和n-1个圆盘之间的关系是什么。n个和n-1个差的就是下面最大的那个圆盘。需要注意:不是表面上move(n, a, b, c)和move(n-1, a, b, c)的关系。 虽然得到move(n, …)要先做move(n-1, …),但如果move(n, a, b, c)的前一步如果是 move(n-1, a, b, c),那也就是a上面n-1个圆盘已经到了c上,那a上剩下最大的那个圆盘还是不能挪动到c上。我们实际要做的是:先把n-1个圆盘挪动到b柱子上,再把a上最后的大圆盘挪动到c上,最后把b上的n-1个圆盘挪动到c上。

4、那么如何:“先把n-1个圆盘挪动到b柱子上”。这时就要相信def move(n, a, b, c) 就像一个神奇的咒语。虽然还没定义完这个函数,但它已经有了“生命”可以实现我们的愿望了。也就是调用它就可以实现汉诺塔搬移。这时,要把a上的n-1个圆盘,通过c柱子的帮助,挪动到b柱子上。起始柱子是a,辅助柱子是c,终点柱子是b。这样就可以调用递归函数 move(n-1, a, c, b)

5、下一步是:“再把a上最后的大圆盘挪动到c上”,我们可以写成 print(a ‘–>’ c)。同样也可以写成 move(1, a, b, c) 因为 n==1得到的基础结果或答案就是print(a ‘–>’ c)

6、最后一步是:“最后把b上的n-1个圆盘挪动到c上”。还是使用magic word。 move(n-1, b, a, c) 表示,这时n-1个圆盘在b上,通过a柱子的帮忙,挪动到c上。

完整的函数就可以写出来了:

def move(n, a, b, c):

if n == 1:

    print(a '-->' c)

else:

    move(n-1, a, c, b)

    print(a '-->' c)  #或者写成 move(1, a, b, c)

    move(n-1, b, a, c)

最后再唠叨两句(我比较墨迹):

1、不要被参数叫a、b、c这些名字所迷惑。要知道这个参数位置真正表示的是什么意思。第一个参数表示是圆盘数量,第二个参数表示“起始柱子”,第三个参数表示“辅助柱子”,第四个参数表示“终点柱子”。也就是从哪个柱子开始搬运,哪个柱子名字就放在第二个参数位置。谁是辅助,谁的名字就在第三个参数位置上。谁是终点,谁的名字就在第四个参数位置上。

2、递归函数要有递归的基础,递归的规律,并且通过分支结构(if…else…)把基础和规律分开。

3、递归基础的语句是要给个确定的结果。一般递归是n == 1 或者 n0开始的。也就是if n == 1 : xxx 或者 if n0: xxx 甚至有可能是if n== 0 or 1: xxx。有的递归可能有多个基础(比如斐波那契数列)

4、递归规律的语句要体现func(n)和func(n-1)的关系,也就是 else :yyy func(n-1) yyy。或者说,else语句要用到你定义的这个函数本身func(n-1)才能实现递归。(当然可能有时候不光要用n-1甚至还会用到n-2或者更多)

5、考查一下自己是否真的完全理解的话,可以这样试试,还是这个递归函数 def move(n, a, c, b) 第一个参数是圆盘数量,第二个参数还是“起始柱子”,第三个参数是“终点柱子”,第四个参数是“辅助柱子”。要如何修改这个函数才能得到相同的答案呢~~~

我把这个回答也粘贴到了zhihu同名问题下:https://www.zhihu.com/question/37152936/answer/728940730

3.angularJS之$apply()方法

       this.loopChange = function() {
                        var caremaList = document.getElementsByTagName("video");
                        console.log(caremaList);
                        for (var i = 0; i < caremaList.length; i++) {
                            //使用匿名函数绑定事件,防止闭包中出现错误
                            (function(index) {
                                caremaList[index].onended = function() {
                                    if (index == 7) {
                                        that.m_oParams.activeIndex = 1;
                                    } else {
                                        that.m_oParams.activeIndex = index + 2;
                                    }
                                    //应用值改变
                                    _oStatusScope.$apply();
                                };
                            })(i);
                        }
                    };

当在4.0里的service层改变视图层$scope的值时,有时候需要_oStatusScope.$apply();来应用。不然会导致值改变了,但是没有应用到视图层。这和vue不太一样,vue是自动响应式的

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值