递推与递归

1、递推算法

递推算法是一种用若干步可重复的简运算(规律)来描述复杂问题的方法。函数

递推是序列计算机中的一种经常使用算法。它是按照必定的规律来计算序列中的每一个项,一般是经过计算机前面的一些项来得出序列中的指定项的值。其思想是把一个复杂的庞大的计算过程转化为简单过程的屡次重复,该算法利用了计算机速度快和不知疲倦的机器特色。spa

例1:植树节那天,有五位同窗参加了植树活动,他们完成植树的棵树都不相同。问第一位同窗植了多少棵时,他指着旁边的第二位同窗说比他多植了两棵;追问第二位同窗,他又说比第三位同窗多植了两棵;... 如此,都说比另外一位同窗多植两棵。最后问到第五位同窗时,他说本身植了10棵。到底第一位同窗植了多少棵树?设计

分析:设第一位同窗植树的棵树为a1,欲求a1,需从第五位同窗植树的棵数a5入手,根据“多两棵”这个规律,按照必定顺序逐步进行推算:
(1) a5=10;
(2) a4=a5+2=12;
(3) a3=a4+2=14;
(4) a2=a3+2=16;
(5) a1=a2+2=18;blog

var
  i,a:byte;
begin
  a:=10;
  for i:=1 to 4 do a:=a+2;
  writeln('The Num is',a);
end.递归

本程序的递推运算可用下图示表示:
初始值a:=10-----i=1,a=a+2(12)-----i=2,a=a+2(14)------i=3,a=a+2(16)-----i=4,a=a+2(18)----输出a值数学

例2:十本不一样的书放在书架上,现从新摆放,使每本书都不在原来放的位置,有几种摆法?it

分析:当n个元素放在n个编号位置,元素编号与位置编号各不对应的方法数用M(n)表示,那么M(n-1)就表示n-1个编号元素放在n-1个编号位置且各不对应的方法数,其它类推。io

第一步,把第n个元素放在除n之外的某一个位置,好比位置k,一共有n-1种方法
第二步,放编号为k的元素,这时有两种状况:
一、把它放到位置n,那么对于剩下的n-2个元素,就有M(n-2)种方法
二、不把它放到位置n,这时对于这n-1个元素有M(n-1)种方法function

综上获得:
M(n)=(n-1)*[M(n-2)+M(n-1)] (n>=3)

var
  n,i:byte;
  a,b,c:longint;
begin
  readln(n);
  case n of
    1: writeln(0);
    2: writeln(1);
  else begin
    a:=0;b:=1;
    for i:=3 to n do begin
      c:=(i-1)*(a+b);
      a:=b;b:=c;
    end;
    writeln(c);
  end;
  end;
end.

递推算法以初始(起点)值为基础,用相同的运算规律,逐次重复运算,直至运算结束。这种从“起点”重复相同的方法直至到达必定“边界”,犹如单向运动,用循环能够实现。递推的本质是按规律逐次推出(计算)先一步的结果。

 

2、递归

若是函数体或过程体中出现调用其自身的语句,称为递归调用。这样的函数或过程称为递归函数或递归过程。

 

例3:设计一个计算n!的递归程序

根据数学含义,n!可由下面的公式表示:

n!=1            当n=0时

n!=n*(n-1)!  当n>0时

根据以上公式推理,为了求n!能够先求出(n-1)!,为了求(n-1)!又能够先求出(n-2)!……,如此递推,直到n=0。因为n=0时已定义为1,再由0!=1又一步步反向推回,求出1!、2!……最终获得n!

 

var

  n:integer;

function fct(t:integer):integer;

begin

  if t=0 then fct:=1

         else fct:=t*fct(t-1);

end;

begin

  readln(n);

  writeln(n,'!=',fct(n));

end.

 

例4:汉诺(hanoi)塔问题。给定三根杆A、B、C和大小不一样的几个盘子,这些盘子按尺寸递减顺序套在A杆上,如图。咱们的任务是把这些盘子从A杆移到C杆且保持原来堆放顺序;在实现任务时,规定每次只能移动一个盘子,不容许大的盘子放在小的盘子上面,B杆能够做为辅助存放杆,求出每一步应该如何移动。

递推与递归 - 徐老师 - Pascal程序设计

 

题目要求将n个盘子由A杆移到C杆可用一样的方法:

一、先(递归地)将A杆上面的n-1个盘子移到B杆(借助C杆)

二、而后把A杆上惟一的一个盘子移到C杆

三、再把B杆上的n-1个盘子(递归地)移到C杆(借助A杆)

 

var

  n:integer;

procedure move(n:integer;a,b,c:char);

begin

  if n=1 then writeln(a,'--->',c)

         else begin

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

    writeln(a,'--->',c);

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

  end;

end;

begin

  readln(n);

  move(n,'A','B','C');

end.

 

递归结构的程序具备结构清晰,容易阅读和理解的优势,写出的程序较简短,但在处理递归问题中,须要保留每次递归调用时的参数和局部变量,这样就占用大量的存储空间和花费较多的机器时间,效率较低。

 

用递归过程或函数解决问题时应注意:

一、求解的问题是否符合递归的描述,要解决的问题是否能够化为与原问题相同的子问题

二、过程体或函数体中必须有递归结束的条件,这个条件就是递归边界

 

3、做业

一、zerojudge:a21六、a04二、b12七、a51九、d580、d2十二、d810

二、用递归方法求两个正整数的最大公约数

三、读入一个任意位数的正整数,按颠倒过来的顺序将其输出(利用递归过程)

四、从键盘输入任意长度的一串字符,其中包括数字和字母,并以星号“*”结束。利用递归的方法将这串字符中的数字字符按相反的次序个输出。例如:输入Delphi6TP70Ada586*,输出为685076。

相关文章
相关标签/搜索