Java笔记day08
一、一维数组应用举例
1、数组获取最值(获取数组中的最大值最小值)
分析:
1)、定义一个数组,存储一些元素(使用静态初始化)
2)、首先在数组中任意找一个元素进行比较,默认一开始它就是最大值
一般来说,我们取第一个(选择排序)
3)、遍历其他的元素与第一个元素进行比较,如果找到了更大的元素,
就将它取代,如果比它小,不管它继续和后面比较
4)、输出最大值
public class ArrayTest1 {
public static void main(String[] args) {
int[] arr = new int[]{1, 3, 543, 623, 34, 43, 54, 23, 6, 4, 235, 53, 2, 720, 903, 206};
int max = arr[0]; //定义数组,并把第一个值赋给max
for (int i = 0; i < arr.length; i++) {
if (max <= arr[i]) {
max = arr[i];
}
} //max与数组中的数一一比较,并把最大值赋给max
int min = arr[0];
for (int i = 0; i < arr.length; i++) {
if (min >= arr[i]) {
min = arr[i];
}
} //min与数组中的数一一比较,并把最小值赋给max
System.out.println("改数组中最大的数是:" + max);
System.out.println("改数组中最小的数是:" + min);
}
}
****max = 903,min = 1****
2、数组元素逆排序 (就是把元素对调)
分析:
1)、创建数组之后,手动输入数据
2)、第一个与最后一个对调位置,第二个与倒数第二个对调,直到length/2结束
3)、输出
import java.util.Scanner;
public class ArrayTest2 {
public static void main(String[] args) {
System.out.println("请输入您想要逆序的数组:");
Scanner sc = new Scanner(System.in);
int[] arr1 = new int[10]; //创建键盘录入对象
//输入
for (int i = 0; i < 10; i++) {
int i1 = sc.nextInt();
arr1[i] = i1;
}
System.out.println("您输入的数组是:");
outPut(arr1);
System.out.println();
System.out.println("逆序方法一之后的数组是:");
int[] arr2 = niXu(arr1);
outPut(arr2);
System.out.println();
System.out.println("逆序方法二之后的数组是:");
int[] arr3 = niXu2(arr1);
outPut(arr3);
}
//输出方法
public static void outPut(int[] array) {
for (int i = 0; i < array.length; i++) {
System.out.print(array[i] + "\t");
}
}
//逆序过程方法一
public static int[] niXu(int[] array) {
for (int i = 0; i < array.length / 2; i++) {
int temp = array[i];
array[i] = array[array.length - 1 - i];
array[array.length - 1 - i] = temp;
}
return array;
}
//逆序过程方法二
public static int[] niXu2(int[] array) {
//使用两个指针实现
for (int start = 0, end = array.length - 1; start <= end; start++, end--) {
int temp = array[start];
array[start] = array[end];
array[end] = temp;
}
return array;
}
}
****输入十个数得到数组arr1,逆序一之后得到数组arr2,逆序二之后得到数组arr3,数组arr3与arr1是一样的****
3、 数组元素查找(查找指定元素第一次在数组中出现的索引)
键盘录入一个数,去数组中查找
3,13,21,3214,3,12,3,24,3,212,3,1,21,3124,21,3
import java.util.Scanner;
public class ArrayTest3 {
public static void main(String[] args) {
//定义一个数组(静态初始化的方式)
int[] arr = {3, 13, 21, 3214, 3, 12, 3, 24, 3, 212, 3, 1, 21, 3124, 21, 3};
//创建键盘录入对象
Scanner sc = new Scanner(System.in);
System.out.println("请输入您要查找的数字:");
int number = sc.nextInt();
for (int i = 0; i < arr.length; i++) {
if (arr[i] == number) {
System.out.println(number + "数第一次出现在数组中的索引为:" + i);
break;
}
if (i == arr.length - 1) {
System.out.println("您输入的数:" + number + "在数组中没有找到!");
}
}
}
}
****输入想要查找的数据,可以得到它的索引值****
4、注意事项
数组排序和二分查找(后面在数组高级部分讲解)
在IT行业,数据结构尤为重要,后面大部分牵扯到底层优化,架构分析等操作时需要数据结构的相关基础
同时,面试的时候,重点会考察排序和查找算法(掌握非递归的形式实现)
排序:冒泡排序,选择排序,快速排序,堆排序
查找:二分查找
二、二维数组
1、概念
元素是一维数组的数组
举例:
数加科技
{{小王,小李},{小刘,小明},{小朱,小伟}}
2、二维数组的定义格式:
1)、格式1
a、格式一具体内容
数据类型[][] 变量名 = new 数据类型[m][n];
左边:
数据类型:表示最终元素的数据类型
[][]:表示是一个二维数组
变量名:二维数组的名称
右边:
new:表示为二维数组分配内存空间
[m]:表示这个二维数组中有个元素,其中元素表示的是m个一维数组
[n]:表示的是每一个一维数组中有n个元素,元素的数据类型与定义时的数据类型一致
举例:int[][] arr = new int[3][2]
解释:表示的是定义了一个名为arr的二维数组,元素是由3个一维数组组成,其中每个一维数组的元素的个数为2个
譬如{{1,2},{3,4},{5,6}}
注意格式的转换:
a: 数据类型 变量名[][] = new 数据类型[m][n];
b: 数据类型[] 变量名[] = new 数据类型[m][n];
举例:int[][] arr = new int[2][3]; (推荐第一种)
int arr[][] = new int[3][4];
int[] arr[] = new int[2][3];
b、格式一内存初始化过程举例说明
举例
public class Array2Demo1 {
public static void main(String[] args) {
int[][] arr = new int[3][2]; //定义一个二维数组,改数组表示由三个一维数组组成,每个一维数组有两个元素
System.out.println(arr); //输出为[[I@1540e19d,表示的是二维数组在堆内存中的地址值
System.out.println(arr[0]); //输出为[I@677327b6,表示的是第一个一维数组在内存中的地址值
System.out.println(arr[1]); //输出为[I@14ae5a5,表示的是第二个一维数组在内存中的地址值
System.out.println(arr[2]); //输出为[I@7f31245a,表示的是第三个一维数组在内存中的地址值
System.out.println(arr[0][0]); //输出的是第一个一维数组中第一个元素值,默认是0
System.out.println(arr[0][1]); //输出的是第一个一维数组中第二个元素值,默认是0
System.out.println(arr[2][1]); //输出的是第三个一维数组中第二个元素值,默认是0
}
}
内存初始化过程(类似于动态初始化)
int[][] arr = new int[3][2];
System.out.println(arr);
System.out.println(arr[0]);
System.out.println(arr[1]);
System.out.println(arr[2]);
System.out.println(arr[0][0]);
System.out.println(arr[0][1]);
System.out.println(arr[2][1]);
int[][] arr,在栈里生成一个二维数组的地址值(假设为0x0001)并存放,new int[3][2]之后这个地址对应在堆里的一片区域,这个区域分为三个部分
分别存储三个一维数组的地址值ox0001,0x0002,0x0003,而这三个一维数组地址值又分别对应这个堆里的三个区域,三个区域分别存放各自一维数组的元素值
所以输出的前四行为地址值,后面三行没有赋值,是默认的元素值,类似一维数组动态初始化过程里的默认值,都是0
2)、格式2
a、格式二具体内容
数据类型[][] 变量名 = new 数据类型[m][];
左边:
数据类型:表示最终元素的数据类型
[][]:表示是一个二维数组
变量名:二维数组的名称
右边:
new:为二维数组开辟堆内存空间
数据类型:表示的是最终元素的数据类型,每个一维数组中元素数据类型
[m]:这个二维数据由m个一维数组组成
[]:这里暂时不将每个一维数组中的元素个数写死,以将来传入的一维数组元素个数而定
举例:
int[][] arr = new int[3][]
b、格式二内存初始化过程
格式二举例
public class Array2Demo2 {
public static void main(String[] args) {
int[][] arr = new int[3][]; //格式二创建数组,表示的是该二位数组由三个一维数组构成,但是一维数组中元素的个数未定
System.out.println(arr); //输出的是二维数组本身的地址值
System.out.println(arr[0]); //输出的是二维数组中第一个一维数组的地址值 null
System.out.println(arr[1]); //输出的是二维数组中第二个一维数组的地址值 null
System.out.println(arr[2]); //输出的是二维数组中第三个一维数组的地址值 null
//****注:只有new之后才会初始化,在之前并没有初始化,所以地址值为空****//
//System.out.println(arr[0][0]); //java.lang.NullPointerException 暂未赋值,空指针异常,不把该行代码注释的话,会报错后面的代码就不能运行
arr[0] = new int[2]; //初始化一个元素个数为2的一维数组,赋值给二维数组中第一个一维数组
arr[1] = new int[3]; //初始化一个元素个数为3的一维数组,赋值给二维数组中第二个一维数组
arr[2] = new int[4]; //初始化一个元素个数为4的一维数组,赋值给二维数组中第二个三维数组
System.out.println(arr); //输出的是二维数组本身的地址值
System.out.println(arr[0]); //输出的是二维数组中第一个一维数组的地址值
System.out.println(arr[1]); //输出的是二维数组中第二个一维数组的地址值
System.out.println(arr[2]); //输出的是二维数组中第三个一维数组的地址值
System.out.println(arr[1][0]); //获取二维数组中第二个一维数组中的第1个元素,0
}
}
格式二内存初始化
int[][] arr = new int[3][];
System.out.println(arr);
System.out.println(arr[0]);
System.out.println(arr[1]);
System.out.println(arr[2]);
//System.out.println(arr[0][0]);
arr[0] = new int[2];
arr[1] = new int[3];
arr[2] = new int[4];
System.out.println(arr);
System.out.println(arr[0]);
System.out.println(arr[1]);
System.out.println(arr[2]);
System.out.println(arr[1][0]);
int[][] arr,在栈里生成一个二维数组的地址值(假设为0x0001)并存放,new int[3][]之后这个地址对应在堆里的一片区域,这个区域分为三个部分
因为没有初始化,所以后面的这些区域里存放的是空的地址值,即null,arr[0] = new int[2]初始化之后空的地址值会被一维数组的地址值取代
即0x0001,0x0002,0x0003,而这些一维数组中存储的值都是默认值,0
3)、格式3
a、格式三具体内容
数据类型[][] 变量名 = new 数据类型[][]{{元素…},{元素…},{元素…},...};
左边:
数据类型:表示最终元素的数据类型
[][]:表示是一个二维数组
变量名:二维数组的名称
右边:
new:为二维数组在堆内存中开辟空间
数据类型:表示的是最终每个一维数组中元素的数据类型
[][]:表示的是一个二维数组
{{元素…},{元素…},{元素…},...}:
表示的是将来自定义多少个一维数组,以及每个一维数组中的元素个数也可以不一样
举例:
int[][] arr = new int[][]{{1,2},{11,22,33},{100,200,300},{10,20}};
举例解释:
表示的是定义一个二维数组,二维数组中的元素是由4个一维数组组成,
每个一维数组中的元素个数不一样,类似于一维数组的静态初始化,前面的两个格式类似于一维数组的动态初始化
简化格式:
数据类型[][] 变量名 = {{元素…},{元素…},{元素…},...};
举例:
int[][] arr = {{1,2},{11,22,33},{100,200,300},{10,20}};
错误的格式:
不能和格式1,格式2混合使用
int[][] arr = new int[3][]{{1,2},{11,22,33},{100,200,300},{10,20}};
b、格式三内存初始化过程
举例
public class Array2Demo3 {
public static void main(String[] args) {
int[][] arr = {{1,2},{11,22,33},{100,200,300},{10,20,30,40}}; //使用二维数组定义格式3定义
System.out.println(arr); //输出二维数组本身的地址值
System.out.println(arr[0]); //输出二维数组中第一个一维数组的地址值
System.out.println(arr[1]); //输出二维数组中第二个一维数组的地址值
System.out.println(arr[2]); //输出二维数组中第三个一维数组的地址值
System.out.println(arr[3]); //输出二维数组中第四个一维数组的地址值
System.out.println(arr[0][0]); //输出二维数组中第一个一维数组中的第一个元素值
System.out.println(arr[0][1]); //输出二维数组中第一个一维数组中的第二个元素值
System.out.println(arr[2][0]); //输出二维数组中第三个一维数组中的第一个元素值
System.out.println(arr[3][2]); //输出二维数组中第四个一维数组中的第三个元素值
}
}
格式三内存初始化
int[][] arr = {{1,2},{11,22,33},{100,200,300},{10,20,30,40}};
System.out.println(arr);
System.out.println(arr[0]);
System.out.println(arr[1]);
System.out.println(arr[2]);
System.out.println(arr[3]);
System.out.println(arr[0][0]);
System.out.println(arr[0][1]);
System.out.println(arr[2][0]);
System.out.println(arr[3][2]);
int[][] arr,在栈里生成一个二维数组的地址值(假设为0x0001)并存放,该语句右边执行之后,在堆里生成一个区域,
这个区域分四个部分,先存放四个null值,然后四个空值被四个一维数组的地址值取代
而一维数组地址值对应的四个区域将会生成四个不同的一维数组存放默认值,然后再由给出的数组值赋值,二维数组的数据读取也和一维数组一样从0开始
三、二维数组应用举例
1、二维数组遍历
int[][] arr = {{1,2},{11,22,33},{100,200,300},{10,20,30,40}};
分析:
1、先获取每一个一维数组
2、一次遍历每一个一维数组中的元素值
3、如果一个一个的打印,则耗时费力,所以用两个嵌套的for循环打印
public class Array2Test1 {
public static void main(String[] args) {
int[][] arr = {{1,2},{11,22,33},{100,200,300},{10,20,30,40}}; //定义一个二维数组
for(int i=0;i<arr.length;i++){ //针对获取到的每一个一维数组进行遍历
for(int j=0;j<arr[i].length;j++){ //内部for循环遍历的是获取到的每一个一维数组中每个元素值
if(j==0){
System.out.print("二维数组中第"+(i+1)+"个一维数组:["+arr[i][j]+",");
}else if(j==arr[i].length-1){
System.out.print(arr[i][j]+"]");
}else {
System.out.print(arr[i][j]+",");
}
}
System.out.println();
}
}
2、打印杨辉三角形(行数键盘录入)
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
...
分析规律:
1)、任意一行的第一列和最后一列都是1
2)、从第三行开始,每个数据都是它上一行本列与上一行前一列之和
实现步骤:
1)、首先定义一个二维数组,行数为n,键盘录入n,行数与列数是相同的,也是n
2)、首先给二维数组中的每一个一维数组的第一列和最后一列赋值1
3)、按照我们发现的规律,给其他元素进行赋值
从第三行开始,每个数据都是它上一行本列与上一行前一列之和
4)、遍历输出这个二维数组
import java.util.Scanner;
public class Array2Test4 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in); //创建键盘录入对象
System.out.println("请输入杨辉三角的行数n:");
int rowNum = sc.nextInt();
int[][] pascalTriangle = new int[rowNum][rowNum]; //定义一个二维数组
for(int i=0;i<pascalTriangle.length;i++){
pascalTriangle[i][0] = 1; //给二维数组中的每一个一维数组的第一列和最后一列赋值1
pascalTriangle[i][i] = 1; //获取到每一个一维数组,通过索引给第一个元素和最后一个元素进行赋值
}
for(int i=2;i<pascalTriangle.length;i++){ //从第三行开始,每个数据都是它上一行本列与上一行前一列之和
for(int j=1;j<=i-1;j++){
pascalTriangle[i][j] = pascalTriangle[i-1][j] + pascalTriangle[i-1][j-1];
}
}
System.out.println("该杨辉三角如下:"); //遍历输出这个二维数组
for(int i=0;i<pascalTriangle.length;i++){
//针对获取到的每一个一维数组进行遍历
for(int j=0;j<pascalTriangle[i].length;j++){
if(j==0){
System.out.print(pascalTriangle[i][j]+"\t");
}else if(pascalTriangle[i][j]==0){
continue;
}else if(j==pascalTriangle[i].length-1){
System.out.print(pascalTriangle[i][j]);
}else {
System.out.print(pascalTriangle[i][j]+"\t");
}
}
System.out.println();
}
}
}
明天继续