我用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);
}
}
}
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)