Java从入门到放弃05(下)---二维数组的初始化/遍历/求和/利用二维数组输出杨辉三角图形/递归思想/Java实现斐波那契数列

Java从入门到放弃05(下)—二维数组的初始化/遍历/求和/利用二维数组输出杨辉三角图形/递归思想/Java实现斐波那契数列

01 Java中的二维数组初始化问题

  • 初始化方式:动态初始化、静态初始化。

  • 动态初始化:自定义二维数组长度,即自定义二维数组中一维数组的个数。

  • 动态初始化格式:数据类型[ ] [ ] 数组名=new 数据类型[m ] [n ];

    a.m表示这个二维数组有多少个一维数组(必须赋值)

    b.n表示每一个一维数组的元素个数(可以不赋值);若不赋值,堆内存不会对一维数组进行初始化。

    class Array2DPractice01{
        public static void main(String[] args){
            int[][] arr1=new int[3][2];
            System.out.println(arr[0]);//打印二维数组arr1中第一个数组的引用地址值
            System.out.println(arr[0][1]);//打印二维数组中第一个数组的第二个元素
            System.out.println(arr[0][2]);//打印二维数组中第一个数组的第三个元素,(注意未对一维数组赋值的情况下,一维数组个数发生角标越界不会报错)
            int[][] arr2=new int[3][];
            System.out.println(arr[0]);//打印二维数组arr2中第一个数组的引用地址值,由于并未对一维数组的元素个数赋值,因此,堆内存不会对一维数组进行初始化,该条程序语句的执行结果为null(引用数据类型的默认值)
            int[] arr21=new int[3];//对一维数组进行动态初始化
            int[] arr22=new int[3];
            int[] arr23=new int[3];
            arr2[0]=arr21;//给二维数组赋值一维数组
            arr2[1]=arr22;
            arr2[2]=arr23;
           // System.out.println(arr2[0][3]);//由于arr2数组已对一维数组进行赋值,因此,该语句发生角标越界。
        }
    }
    
  • 二维数组注意事项:当使用动态初始化方法初始化二维数组时,如下所示,数组长度设置过大将造成堆内寸溢出。

    int[][] arr = new int[900000000][];
    

  • 静态初始化:
格式:数据类型[][] 数组名=new 数据类型{{元素},{元素},...,{元素}}

以程序为例:

class Array2DPractice02{
    public static void main(String[] args) {
        //二维数组静态初始化
        int[][] arr=new int[][]{{2,4},{10,30},{10,30,40},{10,1}};
        System.out.println(arr.length);//打印二维数组长度
        System.out.println(arr[3][1]);//打印二维数组中第四个一维数组的第二个元素
        //简写方式
        int[][] arr2 ={{2, 4}, {10, 30}, {10, 30, 40}, {10, 1}};
        System.out.println(arr2.length);//打印二维数组长度
        System.out.println(arr2[2][2]);//打印二维数组中第三个一维数组的第三个元素
    }
}
运行结果:4
		1
		4
		40

02 二维数组的遍历问题

  • 总结:外层循环控制二维数组长度,内层循环控制一维数组长度。
class Array2DPractice03{
    public static void main(String[] args){
        int[][] arr={{9,3,4},{8,30,29},{98,90,45,90}};
        for(int i=0;i<=arr.length-1;i++){
            System.out.print("arr["+i+"]的元素有:");
            for(int j=0;j<=arr[i].length-1;j++){
                System.out.print(arr[i][j]+"\t");
            }
            System.out.println();
        }
    }
}
运行结果:arr[0]的元素有:9	3	4	
      	arr[1]的元素有:8	30	29	
		arr[2]的元素有:98	90	45	90	

03 二维数组的求和问题

  • 总结,通过对二维数组的遍历对二维数组进行求和
class Array2DPractice04{
    public static void main(String[] args){
        int[][] arr = {{22, 66, 44}, {77, 33, 88}, {25, 45, 65}, {11, 66, 99}};//用一个二维数组将每个月的营业额按季度存储
        int[] sum1=new int[4];//定义一个长度为4的一维数组用来存储每个季度的营业总额
        int sum=0;//定义一个变量用来存储全年的营业总额
        for(int i=0;i<=arr.length-1;i++){
            for(int j=0;j<=arr[i].length-1;j++){
                sum1[i]+=arr[i][j];//对每季度的营业总额赋值
            }
            System.out.println("第"+(i+1)+"季度销售额为:"+sum1[i]);
            sum+=sum1[i];//对全年的营业总额进行赋值
        }
        System.out.println("全年销售总额为:"+sum);
    }
}
运行结果:第1季度销售额为:132
		第2季度销售额为:198
		第3季度销售额为:135
		第4季度销售额为:176
		全年销售总额为:641
//需求:输出杨辉三角
import java.util.Scanner;
public class Array2DPractice05 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.println("please input the line number");
        int num1=sc.nextInt();
        int[][] arr=new int[num1][num1];
        for (int i = 0; i <=arr.length-1; i++) {//1.每一行的第一个数和最后一个数都是1
            arr[i][0]=1;
            arr[i][i]=1;
        }
        for (int i = 2; i <=arr.length-1; i++) {//从第三行开始,每一行的第二列到倒数第二列结束,中间的数等于上一行的前一列的数和上一行本列的数之和
            for (int j = 1; j <=i-1; j++) {
                arr[i][j]=arr[i-1][j-1]+arr[i-1][j];
            }
        }
        for (int i = 0; i <=arr.length-1; i++) {//遍历二维数组
            for (int j = 0; j <=i; j++) {//j<=i,输出三角形
                System.out.print(arr[i][j]+"\t");
            }
            System.out.println();
        }
    }
}

04 Java中的参数传递问题

  • 以下列程序为例
class Array2DPractice06{
public static void main(String[] args) {
		int a = 10;//实参,基本数据类型,存储在栈内存中
  		int b = 20;
  		System.out.println("a: " + a + ",b: " + b);//1.打印a,b
  		change(a,b);//调用change方法(参数类型为int)
  		System.out.println("a: " + a + ",b: " + b);//4.change方法调用结束后,弹栈。因此,此时打印的a,b为存储在栈内存中的实参。
  		int[] arr = {1,2,3,4,5};//实参,引用数据类型,存储在堆内存中。
  		change(arr);//调用change(参数类型为引用数据类型,形参的改变会影响实参。)
  		System.out.println(arr[1]);//5.打印数组中的第二个元素,此时该元素应为调用change方法后的值。
  	}
  	public static void change(int a,int b)  {
  	
  		System.out.println("a: " + a + ",b: " + b);//2.打印传递过来的a,b
  		a = b;
  		b = a + b;
  		System.out.println("a: " + a + ",b: " + b);//3.打印改变后的a,b
  	}
  	
  	public static void change(int[] arr){
  		for(int x = 0 ; x < arr.length ; x++){
  			if(arr[x]%2 == 0){
  				arr[x] *= 2;
  			}
  		}
  	}
  }
  运行结果:a: 10,b: 20
		  a: 10,b: 20
		  a: 20,b: 40
		  a: 10,b: 20
   		  4
  • 总结:1.基本数据类型,作为参数传递,形参的改变,不影响实参(方法执行完毕形参会弹栈,从栈内存中弹出。实参作为局部变量存储在栈内存里)。

    ​ 2.引用数据类型,作为参数传递,形参的改变,会影响实参(引用数据类型存储在堆内存里,形参的改变对同一地址值的实参执行了覆盖,因此会改变实参的值)。


05 递归思想

  • 递归:在方法中调用方法本身,或循环调用该方法。
  • 递归注意的事项:1.递归要有出口,没有出口就是死递归,死递归会造成栈溢出
    2.递归的次数不宜过多,过多也会造成栈溢出。
  • 递归所体现的思想:拆分合并的思想
class RecursionPractice01{
	//计算1~100之间的整数和,拆分成100+99到1之间的整数和,100+99+98到1之间的整数和,依次类推...
    public static void main(String[] args){
        int sum=add(100);
		System.out.println("和为"+sum);
    }
    public static int add(int a){
        if(a==1){
            return 1;
        }else{
            return a+add(a-1);
        }
    }
}
运行结果:和为5050
class RecursionPractice02{
	//计算10的阶乘,拆分成10*9!,10*9*8!,依次类推...
    public static void main(String[] args){
        int product=factorial(10);
        System.out.println("10的阶乘等于"+product);
    }
    public static int factorial(int a){
        if(a==1){
            return 1;
        }else{
            return a*factorial(a-1);
        }
    }
}
运行结果:10的阶乘等于3628800
class RecursionPractice02{
    //斐波那契数列:前两个数为1,从第三个数开始,这个数等于前两个数之和 
    //将该问题拆分为第三十项元素为第29项元素加第28项元素,第29项元素为第28加第27项元素,依此类推,直至拆分到第一项和第二项。返回合并
    public static void main(String[] args){
        int num=fabonacci(30);//斐波那契数列第30项元素
        System.out.println("斐波那契数列第30项元素为:"+num);
    }
    public static int fabonacci(int a){
        if(a==1|a==2){
            return 1;
        }else{
            return fabonacci(a-1)+fabonacci(a-2);
        }
    }
}
运行结果:斐波那契数列第30项元素为:832040

猜你喜欢

转载自blog.csdn.net/yinyanyao1747/article/details/89205947