Java第五课_函数重载递归和初识数组

1.函数

  • 重载

            // 关键字 :public,static等
            // 保留字 : 关键字的预备役   var,goto
            // jdk11开始,还有JS里var升级为关键字: var  变量名 = 初始值 ;
    
            // 重载 / overload : 在同一个类中,允许函数重名 , 但是他们的 参数列表必须不同.
            //          1.参数个数不同    2. 参数类型不同
            //    注意 : 1.形参的名字  2.返回值类型  这两个因素不同也不能重载
            //例如System.out.println(),就使用到了重载
            System.out.println(123);
            System.out.println("abc");
    
            System.out.println(add(10));
            byte b = 127;
            System.out.println(add(b));
            System.out.println(add(b, 3306));//重载同样适用自动类型转换. 没有定义的函数,如果能自动类型转换,也能正常调用
        }
        // 计算任意个数的加法
        public static double add(int i){
            return ++i;
        }
    
        public static double add(byte i){
            return ++i;
        }
    
        public static double add(int i, int j){
            return i + j;
    
  • 递归

        // recursion/递归 : 函数自己调用自己称为递归
        //      前提 : 必须有结束条件并且不能递归太深
        public static void main(String[] args) {
            // 斐波那契数列 1,1,2,3,5,8,13,21.....
            // 从第二项开始,每一项都等于前两项之和.  n = (n-1) + (n-2)
            System.out.println(recursion(30));
            System.out.println(recursion(5));
        }
    
        static int recursion(int num){
            if (num == 1 || num == 2) {
                return 1;
            }
            return recursion(num - 1) + recursion(num - 2); // n = (n-1) + (n-2)
        }
    
  • 代码优化

            // 问题-----百钱买百鸡:一只公鸡值5元钱,一只母鸡值3元钱,三只小鸡值1元钱。  现用百元买百鸡,请问各多少只鸡。
    
            // 第一个程序,单纯的三次循环,各100次
            long startTime = System.nanoTime();// 获得当前时间(纳秒) 等同于 Date中的getTime();
            for (int x = 0; x <= 100; ++x) {
                for (int y = 0; y <= 100; ++y) {
                    for (int z = 0; z <= 100; ++z) {
                        if (x + y + z == 100 && 5 * x + 3 * y + z / 3 == 100 && z % 3 == 0) {
                            System.out.println("x = " + x + " , y = " + y + " , z = " + z);
                        }
                    }
                }
            }
            long endTime = System.nanoTime();// 程序结束时间
            System.out.println((endTime - startTime) + " 纳秒! ");
    
            // 第二个程序,因为公鸡不可能超过25,母鸡33,所以设定时无需100次循环
            startTime = System.nanoTime();
            for (int x = 0; x <= 25; ++x) {
                for (int y = 0; y <= 33; ++y) {
                    for (int z = 0; z <= 100; ++z) {
                        if (x + y + z == 100 && 5 * x + 3 * y + z / 3 == 100 && z % 3 == 0) {
                            System.out.println("x = " + x + " , y = " + y + " , z = " + z);
                        }
                    }
                }
            }
            endTime = System.nanoTime();
            System.out.println((endTime - startTime) + " 纳秒! ");
    
            // 第三个程序,小鸡必然是3只一起,因此也无需100次循环
            startTime = System.nanoTime();
            for (int x = 0; x <= 25; ++x) {
                for (int y = 0; y <= 33; ++y) {
                    for (int z = 0; z <= 100; z += 3) { // z+=3,无需+1+1进行
                        if (x + y + z == 100 && 5 * x + 3 * y + z / 3 == 100) {
                            System.out.println("x = " + x + " , y = " + y + " , z = " + z);
                        }
                    }
                }
            }
            endTime = System.nanoTime();
            System.out.println((endTime - startTime) + " 纳秒! ");
    
            // 第四个程序 x + y + z == 100,因此z = 100 - x - y. 小鸡无需再循环,两个循环就可以
            startTime = System.nanoTime();
            for (int x = 0; x <= 25; ++x) {
                for (int y = 0; y <= 33; ++y) {
                    int z = 100 - x - y;
                    if (5 * x + 3 * y + z / 3 == 100 && z % 3 == 0) {
                        System.out.println("x = " + x + " , y = " + y + " , z = " + z);
                    }
                }
            }
            endTime = System.nanoTime();
            System.out.println((endTime - startTime) + " 纳秒! ");
    
            // 第五个程序 在第四个程序的基础上,将z % 3 == 0提前.
            // 因为 z % 3 == 0 计算量小,&&后如果false,后面运算量较大的表达式,就不用再执行了
            startTime = System.nanoTime();
            for (int x = 0; x <= 25; ++x) {
                for (int y = 0; y <= 33; ++y) {
                    int z = 100 - x - y;
                    if (z % 3 == 0 && 5 * x + 3 * y + z / 3 == 100) { // 将z % 3 == 0提前
                        System.out.println("x = " + x + " , y = " + y + " , z = " + z);
                    }
                }
            }
            endTime = System.nanoTime();
            System.out.println((endTime - startTime) + " 纳秒! ");
    
            // 第六个程序 直接在开头声明x,y,z.这样第二个循环时,不用每次都对y,z 声明-赋值,只需要赋值即可,节省了一个步骤
            startTime = System.nanoTime();// 单位纳秒
            for (int x = 0, y, z; x <= 25; ++x) {
                for (y = 0; y <= 33; ++y) {
                    z = 100 - x - y;
                    if (z % 3 == 0 && 5 * x + 3 * y + z / 3 == 100) {
                        System.out.println("x = " + x + " , y = " + y + " , z = " + z);
                    }
                }
            }
            endTime = System.nanoTime();// 单位纳秒
            System.out.println((endTime - startTime) + " 纳秒! ");
            /*
                总结:提升程序效率基本有两点
                1.考虑需求的实际情况,在逻辑层面,减少对于不可能(不必要)情况的判定.尤其是一些数学问题,考虑清楚逻辑,可以减少很多无意义运算.
                2.注意Java语言本身的特性,在语言特性方面,例如程序五,程序六,减少无效操作.也可以提升效率.
            */
    

2.数组

  • 初识数组

            /*
                数组/Array : 一组相同类型的数据的组合
                声明 :
                    1.数据类型[] 数组名; // 开发推荐
                    2.数据类型 数组名[];
             */
            int[] arr1;
    
            // 初始化 :
            // 1.静态初始化 :  数据类型[] 数组名  =  new  数据类型[]{具体的变量(元素),多个元素之间逗号隔开} ;
            arr1 = new int[]{}; // 没有元素的数组称为空数组 , 就是元素个数为 0 的数组
            int[] arr2 = {1,2,3}; // 如果声明和赋值一起,可以用这种写法,不然
            //arr1= {1,2,3}; 声明和赋值不一起,就不能这样写,只能用下面方式赋值:
            arr1 = new int[]{5,6,7};
    
            // 数组中元素的个数 :  数组名.length
            System.out.println("arr1.length = " + arr1.length);
            System.out.println("arr2.length = " + arr2.length);
    
            // 区分元素 :  数组名[索引值]
            // 索引值/index : 从 0 开始 依次递增    最后一个元素的索引值 :数组名.length - 1
            System.out.println(arr2[arr2.length - 1]);
    
            //数组变量本身记录的值,是数组的地址
            System.out.println(arr1);// [: 数组      I : int    @ : 分隔符    1b6d3586 : 十六进制地址值
    
            // 2.动态初始化 :
            // new : 是在堆内存中开辟新的空间
            // 动态声明 : 数据类型[] 数组名 = new 数据类型[元素个数] ;
            int[] arr3 = new int[5];
            int[] arr4 = new int[5];
            System.out.println(arr1 == arr2);// false,new会开辟新空间
    
            System.out.println(arr3[0]);
            // 动态声明的数组都是有默认值的.数值是0,字符是' ',布尔是false
    
  • 数据传递

        public static void main(String[] args) {
            /*
                调用函数时,需要注意:
                    1.基本数据类型之间是值传递
                    2.引用数据类型之间是地址值传递
                不然会有意料外的值变动
             */
    
            int i = 10;
            int result = m1(i);
            System.out.println("i = " + i);// 10
    
            int[] arr = {10, 10, 10};
            m2(arr);
            System.out.println(arr[0]);// 11
        }
    
        private static int m1(int num) {
            return ++num;
        }
    
        private static void m2(int[] array) {
            ++array[0];
        }
    
posted @ 2023-12-07 22:51  张心野  阅读(15)  评论(0)    收藏  举报