zoukankan      html  css  js  c++  java
  • 递归转非递归(13条消除规则)

    直接递归的消去规则:
     基本思路:将递归调用的地方用等价的非递归代码来代替,并对return语句做适当处理。
    13条规则:处理直接递归调用和return语句,将之转换成等价的迭代代码。

    初始化  
       ⑴ 在过程的开始部分,插入说明为栈的代码并将其初始化为空:  StackType Stack[1..SIZE]
          Top ← 0
        在一般情况下,这个栈用来存放参数、局部变量和函数的值、每次递归调用的返回地址。
       ⑵ 将标号L1附于第一条可执行语句。
          ...  
       L1:第一条可执行语句
          ...
     然后对于每一处递归调用都用一组执行下列规则的指令来代替。
     处理递归调用语句
      ⑶ 将所有参数和局部变量的值存入栈。
         Top ← Top +1
         Stack[Top] ← …
         栈顶指针可作为一个全程变量来看待。
      ⑷ 建立第i个新标号Li,并将标号的下标i存入栈。这个标号的i值将用来计算返回地址。
         Top ← Top +1
         Stack[Top] ← i
         此标号放在规则⑺所描述的程序段中。
      ⑸ 计算这次调用的各实在参数(可能是表达式)的值,并把这些值赋给相应的形式参数。

      ⑹ 插入一条无条件转向语句转向过程的开始部分:
          goto L1

      (以上完成一次递归调用)
    对退出点的处理
      ⑺ 如果这过程是函数,则对递归过程中含有此次函数调用的那条语句做如下处理:将该语句的此次函数调用部分用从栈顶
    取回该函数值的代码来代替,其余部分的代码按原描述方式照抄,并将⑷中建立的标号附于这条语句上。


       如果此过程不是函数,则将⑷中建立的标号附于⑹所产生的转移语句后面的那条语句。

    以上步骤消去过程中的递归调用。

    下面对过程中出现return语句进行处理。
      注:纯过程结束处的end可看成是一条没有值与之联系的return语句
    对每个有return语句的地方,执行下述规则:
     
      ⑻ 如果栈为空,则执行正常返回。
         if top = 0 then return(…)
     
      ⑼ 否则,将所有输出参数(带有返回值的出口参数,out/ inout型)的当前值赋给栈顶上的那些对应的变量。
         
         Stack[n] ← …
      ⑽ 如果栈中有返回地址标号的下标,就插入一条此下标从栈中退出的代码,并把这个下标赋给一个未使用的变量。
         addr ← Stack[Top]
         Top ← Top -1
      ⑾ 从栈中退出所有局部变量和参数的值并把它们赋给对应的变量。

      ⑿ 如果这个过程是函数,则插入以下指令,这些指令用来计算紧接在return后面的表达式并将结果值存入栈顶。
         Top ← Top +1
         Stack[Top] ←表达式的值

      ⒀ 用返回地址标号的下标实现对该标号的转向。
         if addr = i then goto Li



  • 相关阅读:
    FZU 2098 刻苦的小芳(卡特兰数,动态规划)
    卡特兰数总结
    FZU 1064 教授的测试(卡特兰数,递归)
    HDU 4745 Two Rabbits(区间DP,最长非连续回文子串)
    Java 第十一届 蓝桥杯 省模拟赛 正整数的摆动序列
    Java 第十一届 蓝桥杯 省模拟赛 反倍数
    Java 第十一届 蓝桥杯 省模拟赛 反倍数
    Java 第十一届 蓝桥杯 省模拟赛 反倍数
    Java 第十一届 蓝桥杯 省模拟赛 凯撒密码加密
    Java 第十一届 蓝桥杯 省模拟赛 凯撒密码加密
  • 原文地址:https://www.cnblogs.com/xiaowei-blog/p/3796032.html
Copyright © 2011-2022 走看看