递归
在数学与计算机科学中,是指在方法的定义中使用方法自身。也就是说,递归算法就是 一种直接或间接调用自身方法的算法。简言之,在定义自身的同时有出现自身的直接或间接调用。
注意
递归必须有一个退出的条件
递归算法解决问题的特点
1 递归就是方法里调用自身
2 在使用递归策略时,必须有一个明确的递归结束条件,称为递归出口
3 递归算法解题通常显得很简洁,但递归算法解题的运行效率较低。所以一版不提倡借用递归算法设计程序
4 在递归调用的过程当中系统为每一层的返回点、局部量等开辟了栈来存储。递归次数越多越容易造成溢出
(不提倡使用递归解决问题)
//求n的阶乘的递归函数
public int digui(int n){
if(n==1)//如果是n==1 递归结束
return 1;
return n*digui(n-1);//调用自身返回结束
}
以上代码是求n的阶乘的递归函数。如果n==1,到了递归出口,否则调用自身算阶乘
总结
1 找到一种划分的方法
2 找到递推公式或者等价转换这些都是父问题转化为求解子问题
找变化的量:变化的通常要作为参数 找出口
代码示例
递归方法名(参数){
if(判断你是否达到出口){
return;//结束递归
}
调用自身(参数);//递归逻辑
return;
}
例题实战 1
题目大意
斐波那契数列的定义为F(n)=F(n-1)+F(n-2),同时F1=1,F2=1,请你输出数列的第n个数的对1e9+7取模的值.
package Absent;
import java.util.*;
//对字符串
public class Main4 {
public static void main(String args[]) {
Scanner scan=new Scanner(System.in);
int n=scan.nextInt();
System.out.print(F(n));
}
public static long F(int n) {
if(n==2||n==1) {
return 1;
}
long res= F(n-1)+F(n-2);
res%=(long)1e9+7;
return res;
}
}
例题实战 2
题目
我们要求找出具有下列性质数的个数(包含输入的自然数n)
先输入一个自然数n(n<1000)然后对此自然数按照如下方法进行处理
1 不做任何处理
2 在它的左上角加上一个自然数,但该自然数不能超过原数的一半
3 加上数后,继续按此规则进行处理,直到不能再加自然数为止
输入描述
输入一个正整数n
输出描述
输出一个整数,表示具有该性质数的个数
package Absent;
import java.util.*;
//对字符串
public class Main4 {
public static void main(String args[]) {
Scanner scan=new Scanner(System.in);
int n=scan.nextInt();
F(n);
System.out.print(ans);
}
static int ans=1;
public static void F(int n) {
if(n==1) {
return ;
}
for(int i=1;i<=n/2;i++) {
F(i);
ans++;
}
}
}
进制转换
进制的概念
在计算机汇编语言中,常用的进制有二进制、八进制和十进制
数制的表示有2种方法,一种表示方法是数字下标法,对于不同进制的数可以将他们加上括号再用数字下标表示进制:
例如:(110010011111)2代表二进制数:(6137)8代表八进制数
常见进制的运算规则
二进制:逢二进一
基数为2,数值部分用两个不同的数字0、1表示
十进制:逢十进一
基数为10,数值部分用0、1、2、3、4、5、6、7、8、9表示
十六进制:逢十六进一
基数是16,有十六种数字符号,除了在十进制中的0至9外,还另外用6个英文字母A,B,C,D,E,F来表示十进制数的10至15
转换的模板
十进制转n进制模板
x表示十进制的某个数,n是转换成什么进制
public static String con(int x,int n){
StringBuilder str1=new StringBuilder();
while(x>0){
str1.append(x%n);//取每一位的值
x/=n;
}
return str1.reverse().toString();//返回反转字符串
}
例题实战 1
题目
小明要用二进制来表示1到10000的所有整数,要求不同的整数用不同的二进制数表示,请问,为了表示1到10000的所有整数,至少需要多少个二进制位?
运行限制
最大运行时间:1s
最大运行内存:128M
package Accommodate;
import java.util.*;
public class Main5 {
public static void main(String args[]) {
Scanner scan=new Scanner(System.in);
int res=0,sum=0;//需要多少的二进制位
for(int i=0;;i++) {
sum+=Math.pow(2, i);
if(sum>=10000) {
res=i+1;
//二进制从0开始需要加上1,在sum的过程中0不被算入
break;
//不终止,它会反复进行下去,导致报错
}
}
System.out.println(res);
}
}
例题实战 2
题目
请问十六进制数2021ABCD对应的十进制是多少?
package Accommodate;
import java.util.*;
//十六进制转二进制
public class Main6 {
public static void main(String args[]) {
Scanner scan=new Scanner(System.in);
String str=new String();
str="2021ABCD";
int k=0;
long sum=0;
//没有反转的方法,就使用循环语句
for(int i=str.length()-1;i>=0;i--,k++) {
char c = str.charAt(i);
/*
* char字符运算与数形运算不同,
* char运算用到的是ASCII码
* s.charAt(1)是1,对应的ASCII码为49,
* 0的ASCII码(48)
* 以此只有减去48,才能得到第一个数:1
*/
if(c>='A'&&c<'E') {
int res = c-'A'+10;
sum+=(long)Math.pow(16,k);
}else {
int res=c-'0';//转成数字值
sum+=(long)res*Math.pow(16, k);
}
}
System.out.println(sum);
}
}