递归

在数学与计算机科学中,是指在方法的定义中使用方法自身。也就是说,递归算法就是 一种直接或间接调用自身方法的算法。简言之,在定义自身的同时有出现自身的直接或间接调用。

注意

递归必须有一个退出的条件

递归算法解决问题的特点

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);
			
	}
}