求经典的递归算法以及案例(可用C#、PHP、JAVA其中一种语言来写)!

求经典的递归算法以及案例(可用C#、PHP、JAVA其中一种语言来写)!,第1张

我用C#来写(注意,更多的请直接到我的个人博客,点击, http://wwwcnblogscom/serviceboy/archive/2009/07/19/1526590html,收看) 例1有甲、乙、丙、丁四人,从甲开始到丁,一个比一个大1岁,已知丁10岁,问甲几岁?分析这是递归法的一道非常典型的题目——因为我们可以很显然知道:假设要计算甲的年龄,那么必须直到乙的年龄;同样,算乙的必须直到丙的,算丙的必须知道丁的,因为丁已知,自然可以往前推算了。现在假设有一个数学模型(函数)可以计算出他们各自的年龄(方便期间我们给他们编号——甲=1,乙=2,丙=3,丁=4),那么存在这一个F(X)函数,X表示某人的编号,其规律如下:F(1)=F(2)+1F(2)=F(3)+1F(3)=F(4)+1F(4)=10显然,直到X=4的时候是一个终止值,其余情况下都是返回F(X’),F(X’’)……F(X’’……’),且前者总是比后至大1,这也符合了X’和X总是呈现一定函数关系(设想一下,如果不是等差和等比,又怎么可能在一个递归函数中进行计算?要知道,函数本身就是一个公式表示,既然是公式,那么一定是一种函数关系Y=F(X)),此处显然X和X’的关系是X=X’+1。根据规律式,我们可以写出该递归函数:int AgeCal(int id)

{

if(id==4) return 10;

else

return (AgeCal(id+1)+1);

} 例2计算n!分析虽然这道题目不像例1一样清晰明了告诉你使用“递归”法反推,但是我们有这样一个常识——n!=(n-1)!n;(n-1)!=(n-2)!(n-1)……n=0或1,返回1显然n与n-1,n-2也是线性的递减数列(等差关系)。其规律如下:F(n)=F(n-1)nF(n-1)=F(n-2)(n-1)F(n-2)=F(n-3)(n-2)……F(1)=1或者F(0)=1(防止别人直接输入0)编写其递归函数,如下:int Fac(int n)

{

if(n==1 || n==0)

{

return 1;

}

else

return Fac(n-1)n;

} 例3求一组整数中的最大(小)值(整数是一个int[]数组,个数未知)。分析当数字只有两个的时候,我们可以使用>和<直接比较;但是当数字超过2个的时候(假设3个),那么我们可以使用一个预订的函数(比如Max(1,2)和3进行比较),由于1,2两个数比较的时候已经得到一个最大值,因此在回代到Max中又变成了两个数的比较。这样,我们可以发现一个规律:F(1,2,3,4……n)=F(1,2,3,4……n-1)和n比较F(1,2,3,4……n-1)=F(1,2,3,4……n-2)和n-1比较……F(1,2,3)=F(1,2)和3比较F(1,2)=结果(并回代)相应的递归函数如下(C#):Code

int Max(int[]numbers)

{

if(numbersLength==2)

{

return (numbers[0]>numbers[1]numbers[0]:numbers[1]);

}

else

{

int[]tempnumbers=new int[numbersLength-1];

for(int i=0;i<numbersLength-1;++i)

{

tempnumbers[i]=numbers[i];

}

return (Max(tempnumbers)>numbers[numbersLength-1] Max(tempnumbers): numbers[numbersLength-1]

}

}

return 1/n + f(n-1);这里错了java中/当两边都是int是它代表取整运算

2种改法:1)int n = consolenextInt();定义n是用double来定义

2)return 1/n + f(n-1);这里讲结果强转为double

import javautilScanner;

public class TestDiGui

{

public static void main(String[] args)

{

Scanner sc = new Scanner(Systemin);

int input = 0;

int show = 0;

Systemoutprintln("输入一个整数n:");

input=scnextInt();

show = f(input);

Systemoutprintln("结果为:"+show);

}

static int f(int n)

{

int result = 0;

if(n==0)

{

result = 0;

return result;

}

if(n==1)

{

result = 1;

return result;

}

else

{

result = n+f(n-1);

return result;

}

}

}

public class Test{

    public static int result(int parameter){

          if(parameter<=1) return 1; // 判断parameter是否小于等于1,如果不成立则递归调用

          int number = parameterresult(parameter-1);  // 将parameter-1继续调用函数 反复如此,直至条件成立。                                            

             return number;

     }

    public static void main(String[]args{

          int result = result(5);

          Systemoutprintln(result);

  }

}

 

它的执行原理是如下这样的:

result(5) 初始时 ==》进入函数体判断parameter是否小于等于1,此时parameter等于5,条件不成立,执行parameterresult(parameter-1) 即5result(5-1),程序反复执行。。。

5result(5-1)

4result(4-1)

3result(3-1)

2result(2-1) 到此 parameter等于1符合条件 函数返回1,层层返回。即:

result(1) =1

2result(1)=21=2

3result(2)=32=6

4result(3)=46=24

5result(4)=524=120

方法递归和循环语句差不多,打个比喻。方法递归是小明上楼拿东西,一楼,二楼,三楼……楼顶。在楼顶拿到想要的东西以后,你总不能直接跳下来吧。你得一层一层的返回下来。循环就是驴拉磨,你转多少圈都是在原地。变化的只是盘子里的东西有变化。方法递归不会进入死循环,但陷的太深系统会崩溃。

答得不好抱歉

是的,这段代码中的递归调用只会返回第一次的返回值。如果你想得到800的结果,可以修改代码,使得第二次递归调用的结果被正确地返回。具体地,你可以在第二次递归调用结束之后,将结果返回到上一层递归调用,并在第一次递归调用结束之后将结果返回。修改后的代码如下:

String deal(String s1, String s2) { if(s1 != null) { if(contact(s1charAt(s1length() - 1)) == 1) {

s1 += s2; return s1;

} else {

s1 = s1substring(0, s1length() - 1);

s1 = deal(s1, s2); // 递归调用并将返回值赋值给s1

return s1; // 将结果返回到上一层递归调用

}

} return s1;

}

int contact(char ch) { if(CharacterisDigit(ch) || ch == '' || ch == '' || ch == '-') return 1; if(ch == '+' || ch == '/') return 2; return 0;

}String str = deal("800-", ""); // 返回的结果为800

1汉诺塔问题

import javaxswingJOptionPane;

  public class Hanoi {

  private static final String DISK_B = "diskB";

  private static final String DISK_C = "diskC";

  private static final String DISK_A = "diskA";

  static String from=DISK_A;

  static String to=DISK_C;

  static String mid=DISK_B;

  public static void main(String[] args) {

  String input=JOptionPaneshowInputDialog("please input the number of the disks you want me move");

  int num=IntegerparseInt(input);

  move(num,from,mid,to);

  }

  private static void move(int num, String from2, String mid2, String to2) {

  if(num==1){

  Systemoutprintln("move disk 1 from "+from2+" to "+to2);

  }

  else {

  move(num-1,from2,to2,mid2);

  Systemoutprintln("move disk "+num+" from "+from2+" to "+to2);

  move(num-1,mid2,from2,to2);

  }

  }

  }

2 这是一个排列的例子,它所做的工作是将输入的一个字符串中的所有元素进行排序并输出,例如:你给出的参数是"abc" 则程序会输出:

  abc

  acb

  bac

  bca

  cab

  cba

  (1)算法的出口在于:low=high也就是现在给出的排列元素只有一个时。

  (2)算法的逼近过程:先确定排列的第一位元素,也就是循环中i所代表的元素,

  然后low+1开始减少排列元素,如此下去,直到low=high

  public static void permute(String str) {

  char[] strArray = strtoCharArray();

  permute(strArray, 0, strArraylength - 1);

  }

  public static void permute(char[] list, int low, int high) {

  int i;

  if (low == high) {

  String cout = "";

  for (i = 0; i <= high; i++)

  cout += list[i];

  Systemoutprintln(cout);

  } else {

  for (i = low; i <= high; i++) {

  char temp = list[low];

  list[low] = list[i];

  list[i] = temp;

  permute(list, low + 1, high);

  temp = list[low];

  list[low] = list[i];

  list[i] = temp;

  }

  }

  }

  3。这是一个组合的例子,与上述的例子相似,只是它所做的工作是,输出所给字符串中制定数目的元素的组合种类

  (1)程序出口在于n=1,此时只要输出目标数组的所有元素即可

  (2)逼近过程,当n>1 的时候,我们先取第一个元素放入目标数组中,然后n-1,如此下去,最后出来。

  import javaxswingJOptionPane;

  public class Combination {

  /

   @param args

  /

  public static void main(String[] args) {

  String input = JOptionPaneshowInputDialog("please input your String: ");

  String numString = JOptionPaneshowInputDialog("please input the number of your Combination: ");

  int num = IntegerparseInt(numString);

  Combine(input, num);

  }

  private static void Combine(String input, int num) {

  char[] a = inputtoCharArray();

  String b = "";

  Combine(a, num, b, 0, alength);

  }

  private static void Combine(char[] a, int num, String b, int low, int high) {

  if (num == 0) {

  Systemoutprintln(b);

  } else {

  for (int i = low; i < alength; i++) {

  b += a[i];

  Combine(a, num - 1, b, i+1, alength);

  b=bsubstring(0, blength()-1);

  }

  }

  }

  }

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/11672478.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-17
下一篇 2023-05-17

发表评论

登录后才能评论

评论列表(0条)

保存