首页 > 编程语言 >【Java复健指南01】简介与数组

【Java复健指南01】简介与数组

时间:2022-10-09 14:01:16浏览次数:48  
标签:复健 arr 01 Java int System length 数组 out

写在最前

学习Java已经是很久之前的事情了,因为技术栈的转变,很久没有使用Java正经地开发过项目。

对于该语言的理解也是停留在表面,因此萌生了重新学习的念头。一方面是为刷算法题打基础,另一方面也是想拓展一下自己的技术栈(要不然失业了都)

既然我的目标是“复健”,那么显然不可能完全重新学习记录一遍。当初学习Java的目的是为了开发Android和制作Minecraft的mod,一些Java的高级部分涉及不多。

因此,本次学习以Java每个部分(从数组往后的)的关键知识点作为展开,会着重记录:

  • 相应部分的一些易错点和对应的练习
  • 编程思想与处理问题的trick
  • 典型的算法题的解法、优化和总结(Java、Python版本)

开始吧~

【数组】

数组的分配方式

一维:

int[] arr = new int[5]; //动态分配

int arr[];
arr = new arr[5];//先定义,后使用

int[] arr = {1,2,3};//直接分配

二维:

int[][] arr = new int[3][2]; //基本用法

int[][] arr = new int[3][]; //后分配数组列数,可用于循环

// 动态初始化
int arr[];//声明二维数组
arr new int[2][3];//再开空间

int[][] arr = {{1,2},{6,7}};//直接分配

数组拷贝

对于基本的数据类型,器赋值过程为值拷贝,赋值完成后修改被赋值变量不会影响原变量的值

而数组不一样

数组被定义之后会开辟一块相应的内存空间,然后该空间的地址传回给数组变量arr1

当数组arr1被拷贝,arr1会复制当前的地址给被赋值的数组变量arr2(该地址指向的空间仍为之前为arr1开辟的那个

因此,当我们对arr2的值进行修改,会影响arr1的值,因为两者指向的实际地址空间一致

数组细节

  • 数组是多个相同类型数据的组合,实现对这些数据的统一管理

  • 数组中的元素可以是任何数据类型,包括基本类型和引用类型,但是不能混用

  • 数组创建后,如果没有赋值,有默认值如下:

    int 0, short 0, byte 0, long 0, float 0.0, double 0.0 ,boolean false, String null
    
  • 数组下标必须在指定范围内使用,否则报:下标越界异常,比如

    int arr=new int[5];//则有效下标为0-4
    
  • 使用数组的步骤
    (1)声明数组并开辟空间
    (2)给数组各个元素赋值
    (3)使用数组

一维数组练习

数组翻转

思路1:

​ 从数组的头部和尾部两个方向向数组中间位置推进,过程中不断交换数组元素

public class ArrayReverse{
	public static void main(String[] agrs){
		/*
		要求:把数组的元素内容反转。
		例如:arr {11,22,33,44,55,66}→{66,55,44,33,22,11}
		思路1:
		规律
		1.把arr[0]和arr[5]进行交换{66,22,33,44,55,11}
		2.把arr[1]和arr[4]进行交换{66,55,33,44,22,11}
		3.把arr[2]和arr[3]进行交换{66,55,44,33,22,11}
		4.一共要交换3次 = arr.length/ 2
		5.每次交换时,对应的下标是arr[i](0,1,2)和arr[arr.length - 1 -i](5,4,3)
		*/
		//定义一个数组
		int[] arr = {11,22,33,44,55,66,77};
        int temp = 0;//临时变量
        for(int i = 0; i < arr.length / 2; i++){
            arr[arr.length - 1 - i] = temp;
            arr[arr.length - 1 - i] = arr[i];
            arr[i] = temp;
        }
        System.out.println("====翻转后的数组====");
		for(int i = 0; i<arr.length; i++){
			System.out.print(arr[i] + "\t");
		}

	}
}

两个注意点:

  • 循环范围是数组长度的一半。这里不论数组的元素个数是单/双数都没关系(反正取整都一样),单数的话中间的那个元素是不用动的(因为不是排序)
  • 循环过程中的元素下标。
    • i表示从数组头部开始向数组尾部的方向;
    • 数组长度-i表示从尾部到头部的方向;

思路2:逆序遍历。即逆序遍历待翻转的数组,然后再顺序存入一个新数组中,最后使原数组指向新数组

 public class ArrayReverse02{
	public static void main(String[] agrs){
		/*
		思路2:
		逆序遍历
		1、逆序遍历待翻转的数组
		2、顺序存入一个新数组内
		3、将原数组的地址指向新数组(旧数组垃圾回收)
		4、在循环中增加一个顺序增加的变量j
		*/
        int[] arr = {11,22,33,44,55,66,77};
        int[] arr2 = new int[arr.length];
        for(int i = arr.length - 1, j = 0; i > = 0; i--, j++){
            arr2[j] = arr[i];
        }
		arr = arr2;//舍弃旧数组
        
        System.out.println("====翻转后的数组====");
		for(int i = 0; i < arr.length; i++){
			System.out.print(arr[i] + "\t");
		}

	}
}

一个注意点:

  • 在循环中,循环变量可以有两个;

冒泡排序

思路:

就是冒泡法的思路。遍历数组,当前的数与下一个数进行比较,若当前数大则与下一个数交换,继续比。若后一个数较大,则指针后移,重复之前的操作。最终的目的是将当前最大的数往数组的末尾移动,完成第一次移动后,我们需要找到第二大的数移动至数组的次末尾,重复上述过程直到排序完成。

因此,排序是分多轮进行的,每轮只能将一个数送至数组的末尾(相对意义上的末尾)

public class BubbleSort{
	public static void main(String[] agrs){
		/*
		将五个无序数24,68,80,57,13使用冒泡排序法排成一个
		从小到大的有序数列

		数组{24,69,80,57,13}
		第1轮排序:目标把最大数放在最后
		第1次比较[24,69,80,57,13]
		第2次比较[24,69,80,57,13]
		第3次比较[24,69,57,80,13]
		第4次比较[24,69,57,13,80]
		*/
		int[] arr = {24,69,80,57,13};
        int temp = 0;
        for(int i = 0; i < arr.length - 1; i++){
            for(int j = 0; j < arr.length - 1 - i; j++){
                if(arr[j]>arr[j+1]){
                    temp = arr[j+1];
                    arr[j+1] = arr[j];
                    arr[j] = temp;
                    /*
                    temp = arr[j];
					arr[j] = arr[j+1];
					arr[j+1] = temp;
                    */
                }
        	}
            System.out.println("\n====第"+(i+1)+"轮====");
			for(int j = 0;j < arr.length; j++) {
				System.out.print(arr[j]+"\t");
			}
        } 
	}
}

几个注意点:

  • 从最基本(核心)的功能开始写,即实现数组前后两个数的比较和交换,然后再考虑重复上述过程
  • 使用临时变量交换的逻辑不要搞混
  • 从第二轮排序开始,其实需要比较的次数是不断变少的,这点体现再内层循环的条件中,即减掉外层循环当前的循环变量,这是一种常规思想

二维数组练习

打印杨辉三角

使用二维数组打印一个10行杨辉三角
			1
			1 1
			1 2 1
			1 3 3  1
			1 4 6  4  1
			1 5 10 10 5 1
		
		【提示】
			1.第一行有1个元素,第n行有n个元素
			2.每一行的第一个元素和最后一个元素都是1
			3.从第三行开始,对于非第一个元素和最后一个元素的元素的值
			  arr[i][j] = arr[i-1][j] + arr[i-1][j-1];

思路:先打印一个从上至下元素(数组长度)增加的三角,然后依据规律往里填数

public class YangHui{
	public static void main(String[] agrs){
		/*
		
		*/
        int[][] arr = new int[10][];
        for(int i = 0; i < arr.length; i++){
            arr[i] = new int[i + 1];//获得一堆三角形数组
            //判断当前的数是否为第三行后数组的第一个数或最后一个数
            for(int j = 0; j < arr[i].length){
                if(j == 0 || j == arr[i].length){
                	arr[i][j] = 1;
                }else{
					arr[i][j] = arr[i - 1][j] + arr[i - 1][j - 1];
                }
            }
            
        }
        System.out.println("杨辉三角");
		for(int i = 0; i < arr.length; i++){
			for(int j = 0; j < arr[i].length; j++){
				System.out.print(arr[i][j] + "\t");
			}
			System.out.println();
		}
	}
}

一个注意点:

  • 二维数组先定义外层,之后再定义内层数组元素是常规用法,这题中有体现

    • 例如

    • //创建二维数组,一共有3个一维数组,
      //但是每个一维数组还没有开辟数值空间
      int[][] arr = new int[3][];//列数不确定
      for(int i = 0; i < arr.length; i++){
      	//给每个一维数组开空间new
      	//如果没有给一维数组new ,那么arr[i]就是null
      	arr[i] = new int[i + 1];
      
      	//遍历一维数组,并给一维数组的每个元秦赋值
      	for(int j = 0; j < arr[i].length; j++){
      		arr[i][j] = i + 1;//赋值
      		}
      
      }
      

数组习题

习题一

已知有个升序的数组,要求插入一个元素,该数组顺序依然是升序,比如:[10,12,45,90],添加23后,数组为[10,12,23,45,90]

思路1:

1、定义一个变量用于接收插入的数
2、遍历数组,与待插入的数比较大小若插入的数小于数组当前遍历到的值,则插入

public class Homework04{
	public static void main(String[] agrs){
		//我的解法
		int[] arr = {10,12,45,90};
		int[] arrNew = new int[arr.length + 1];//用于存放扩充后元素的数组
		int ins = 89;//插入值
		int flag = 0;//用于确定是否插入值的标志位

		System.out.println("====插入元素前的arr====");
		for(int i = 0; i < arr.length; i++) {
			System.out.println(arr[i]);
		}

		for(int i = 0; i < arr.length; i++){
			if(arr[i] > ins && flag == 0){
				arrNew[i] = ins;//满足条件,插入元素
				flag = 1;
				arrNew[i + 1] = arr[i];//将原本应在当前位置的元素顺延至后一个位置
			}else if (flag == 1) {
				arrNew[i + 1] = arr[i];
			}else{
				arrNew[i] = arr[i]; 
			}
		}
		arr = arrNew;

		System.out.println("====插入元素后的arr====");
		for(int i =0; i < arr.length; i++) {
			System.out.println(arr[i]);
		}

	}
}

思路2(标准解法):

本质数组扩容+定位

1.我们先确定添加数应该插入到哪个索引
2.然后扩容

public class Homework04{
	public static void main(String[] agrs){
		//先定义原数组
		int[]arr = {10,12,45, 90};
		int insertNum = 23;
		int index = -1; //index就是要插入的位置
		//遍历arr数组,如果发现insertNum<=arr[i],说明i就是要插入的位置
		//使用index保留index = i;
		//如果遍历 完后,没有发现insertNum<=arr[i],说明index = arr.length
		//即:添加到arr的最后

		for(int i = e; i < arr. length; i++) {
			if(insertNum<= arr[i]){
				index = i;
				break;//找到位置后,就退出
			}
		}

		//判断index的值
		if(index == -1) {//说明没有还没有找到位置
			index = arr. length;
		}
		// System.out. println("index=" + index);

		//扩容
		//先创建一个新的数组,大小arr.length + 1
		int[]arrNew = new int[arr.length + 1];
		//下面准备将arr的元素拷贝到arrNew ,并且要跳过index位置

		for(int i = e, j=0; i < arrNew.length; i++) {
			if( i l= index ) {//说明可以把arr的元素拷贝到arrNew
				arrNew[i]= arr[j];
				j++;
			}else {//i这个位置就是要插入的数
				arrNew[i] = insertNum;
			}
		}
	}
}

习题二

随机生成10个整数(1_100的范围)保存到数组,并倒序打印以及求平均值、求最大值和最大值的下标并查找里面是否有8

public class Homework05{
	public static void main(String[] agrs){
		/*		
		我的思路:
		0、定义一个长度为10的数组
		1、(导入)随机数模块random
		2、通过循环调用random产生10个随机数并保存至数组
		3、定义存放平均值的变量average
		  定义存放最大/小值下标的变量Maxindex/Minindex
		*/

		int[]arr = new int[10];
		//(int)(Math.random() 100)+1 生产随机数1-100
		for(int i = e; i < arr.length; i++){
			arr[i]=(int)(Math.random()*100)+1;
		}

		System.out. println("====arr的元素情况=====");
		for(int i =e; i < arr. length; i++){
			System.out.print(arr[i]+"\t");
		}

		System.out.println("in====arr的元素情况(倒序)=====");
		for(int i =arr.length -1; i >= 0; i--){
			System.out.print(arr[i]+ "\t");
		}
		//平均值、求最大值和最大值的下标
		//
		double sum = 0;
		int max = arr[0];
		int maxIndex = 0;
		for(int i =1; i < arr. length; i++ ){
			
			sum += arr[i];

			if(max < arr[i]){//说明max不是最大值,就变化
			max = arr[i];
			maxIndex = i;
			}
		}
		System.out.println("\nmax=" + max + " maxIndex=" +maxIndex);
		System.out.print1n("\n平均值="+(sum / arr.length);


		//查找数组中是否有8->使用顺序查找
        int findNum = 8;
		int index = -1;//如果找到,就把下标记录到index
		for(inti=0;i<arr.length; i+){
			if(findNum == arr[i){
				System.out.println(“找到数"+findNum + ”下标="+i);
				index = i;
				break;
			}
		}
		if(index == -1){
			System.out.println("没有找到数"+findNum );
		}
	}
}

注意:

本题中有两个常用的手法

1、找出数组中的最大/小值

设置一个变量保存最值,先指定数组的第一个值为最大值,设定一个变量用于记录最值下标。

遍历数组,然后将当前遍历值与设定最大值比较

若发现更大值则更新最值变量和下标变量即可

2、寻找数组中的某个值

设置一个变量用于存放要找的目标值

设置一个变量用于存放下标,初始值为-1

关键点

遍历数组,若找到目标数,返回提示并将下标保存

即刻结束循环遍历

若没有找到,遍历会结束,此时只需判断index是否仍为初始值即刻得知找没找到目标数

标签:复健,arr,01,Java,int,System,length,数组,out
From: https://www.cnblogs.com/DAYceng/p/16771884.html

相关文章

  • Java实现多线程
    Java实现多线程的方式有4种分别是继承Thread类,实现Runnable,Callable接口和通过线程池提交线程任务。其中实现Callable接口的方式可以获取返回值。1.继承Thread类通过继......
  • 浏览器中javascript简易实现json数据保存到客户端
    思路很简单,就是利用Blob、URL.createObjectURL()方法和<a>便签的HTML5新属性download来模拟远端文件下载保存。下面直接上代码savePath:function(){varme......
  • JavaScript异步概念及与c#异步的区别
    JS的异步操作函数往往是通过回调函数来实现异步任务的结果处理,在ES6之前如setTimeout函数和异步AJAX编程;在ES6规范后Promise类对象使得书写异步任务更加容易,返回Promise......
  • java---了解以下运算符
    了解即可1&2用于条件判断,&条件1和2都执行1&&2,条件1判断错误的情况下,条件2不执行&当运算符的化,例如4&7,两者上下对比都是1则为1,反之为0,结果就是二进制100也就是......
  • JAVA中计算两个日期时间的差值竟然也有这么多门道
    JAVA中计算两个日期时间的差值竟然也有这么多门道上半年春招的时候,作为面试官,对于面试表现的不错的同学会要求其写一小段代码看看。题目很简单:给定一个日期,然后计算下......
  • 20201306吴龙灿第三章学习笔记
    目录Ⅰ知识点归纳1.进程的概念·什么是进程?·进程的特征动态性并发性独立性异步性结构性·程序和进程主要区别2.多任务处理系统(1)背景(2)多任务处理系统代码介绍3.进程同步(1)同......
  • Java获取当前系统事件System.currentTimeMillis()方法 ,获取当前时间戳10位 166529114
    Java获取当前系统事件System.currentTimeMillis()方法,获取当前时间戳10位1665291145转为时间字符串yyy-MM-ddSystem.currentTimeMillis()产生一个当前的毫秒,这个毫秒......
  • java获取当前时间戳的三种方法比较效率(*)
    java获取当前时间戳的三种方法比较效率(*)获取当前时间戳//方法一System.currentTimeMillis();//方法二Calendar.getInstance().getTimeInMillis();//方法三ne......
  • Java 时间字符串转成时间戳 2022-10-08 10:47:08 yyyy-MM-dd HH:mm:ss 1665290918
    Java工具类方法时间字符串转成时间戳2022-10-0810:47:08yyyy-MM-ddHH:mm:ss返回时间戳1665290918publiclonggettimeStemp(Stringtime,Stringformat){ Si......
  • java Locale类使用
    1、定义Locale表示地区。每一个Locale对象都代表了一个特定的地理、政治和文化地区。在操作Date,​​Calendar​​等表示日期/时间的对象时,经常会用到;因为不同的区域,时间......