递归
摘要
本文将主要介绍递归。
递归
递归的含义很好理解,就是一个函数调用自身,难就难在如何确定一个题目的递归式,这就需要多刷题了。
一个完整的递归函数包含两个部分:
- 递归式
- 递归出口
以斐波那契数列为例:
int f(int n){
if(n == 1 || n == 2) return 1; // 递归出口
return f(n-1) + f(n-2); // 递归式
}
递归式用来递归计算我们想要得到的值, 递归出口用来结束递归。
如果没有递归出口,那么就会一直递归下去,就造成了死循环。
那么什么题会用到递归呢?
当需要枚举所有的状态时,大部分都可以用递归。
子问题和原问题求解方式完全相同的,可以用递归。
举个例子:
蓝桥杯练习系统 ---计算n阶行列式
计算n阶行列式
给定一个N×N的矩阵A,求|A|。
输入格式:
第一行一个正整数N。 接下来N行,每行N个整数,
第i行第j个数字表示A【i】【j】
输出格式 一行,输出|A|。
行列式计算规则:
A11A12…A1n
A21A22…A2n
…
An1An2…Ann
n==2 : |A| = A11 * A22 - A12*A21
n > 2 : |A| = (-1)i-1A11|A’ | + (-1)i-1 A12 |A’ | + … + (-1)i-1A1n|A’ |
其中, A’ 是原矩阵删去第 1 行和第 i 列后构成的新矩阵。
A B C
D E F = A * E F + B * D F + C * D E
G H I H I G I G H
所以当n == 2时就是递归出口了, n > 2 递归计算。
代码:
import java.io.*;
public class Determinant {
static BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
static BufferedWriter out = new BufferedWriter(new OutputStreamWriter(System.out));
public static int Int(String s) {
return Integer.parseInt(s); //把()里的内容转换成整数
}
public static void copy(int[][]A, int[][]A1, int i, int len)throws IOException {
for (int x=1; x<len; x++) {
for (int y=0,j=0; j<len; j++) {
if (j!=i) {
A1[x-1][y++] = A[x][j]; //相当于3*3计算中A * E F 这一步的实现
} // G H
}
}
}
public static int F(int[][]A, int len)throws Exception {
int res = 0; //保存每个矩阵的|A|
if (len==1) {
return A[0][0];
}
if (len==2) {
return A[0][0]*A[1][1]-A[1][0]*A[0][1]; //递归出口
}
else {
int A1[][] = new int[10][10];
for (int i=0; i<len; i++) {
copy(A,A1,i,len);
res += Math.pow(-1,i)*A[0][i]*F(A1,len-1); //递归式,Math.pow(底数,几次方)
}
}
return res;
}
public static void main(String[] args)throws Exception {
int n;
n = Integer.parseInt(in.readLine());
int arr[][] = new int[10][10];
for (int i=0; i<n; i++) {
String[] s = in.readLine().split(" ");
for (int j=0; j<n; j++) {
arr[i][j] = Int(s[j]);
}
}
out.write(F(arr,n)+"\n");
out.flush();
}
}
练习题目
个人感觉上面的题目对于新手来说太暴力了,有些地方很难理解,有能力的可以一天练习1道。博主感觉当时自学编程,是被很多好看的界面和好玩的程序吸引,当真正研究起算法时,感觉还是很需要扎实的数学功底和分析能力,当然最重要的还是努力了。
然后这是博主看奇淫巧技总结下来的(还会有持续更新):
入门题目
2.蓝桥算法(递归)