1、数组的核心思想
class ArrayTest4 { public static void main(String[] args) { for(int i = 1; i <= 7; i++) System.out.println(getWeek(i)); } /* 数组使用的核心思想: 容器特点:1,固定长度,2,元素都有索引。 什么时候使用容器呢?数据多了,必须先进行存储。然后进行操作。 对于数组容器什么时候用呢?数据多,个数确定,而且有对应关系。 在分析需求时, 1,需求中的数据是否有对应的有序编号? 2,需求中的数据是否需要有序的编号? 如果有,就用数组存储。 例1:一组数:34 89 12 78 45 要对他们进行操作。需要编号,操作更容易。 例2:根据用户输入的数据,显示对应的星期。 思路: 1,星期有多个,个数固定。 2,星期对应的有序编号。有序的编号就可以作为索引。 所以可以使用数组这种结构进行存储。 */ /* 定义一个功能。根据给定的数据获取对应的星期。 查表法:数据之间存在对应关系。通过关系中一方查询另一方。当对应关系存在,但没有一方是有序编号时,使用另一个容器 map。 */ public static String getWeek(int num) { if(num>7 || num<1) return num+"没有对应的星期";//throw new RuntimeExcpetion(num+"没有对应的星期"); //1,定义一个数组,存储固定的星期数。这个称之为一个存储了对应关系的表。 String[] weeks = {"","星期一","星期二","星期三","星期四","星期五","星期六","星期日"}; //其实就是根据制定的索引在查表。 return weeks[num]; } }
2、数组进制运算
class ArrayTest5 { public static void main(String[] args) { int num = 60; String str_hex = toHex(num); System.out.println(str_hex); } /* 需求:十进制-->十六进制。 &15 >>>4 循环 遇到问题: 1,顺序反了。2,去除多余的0. 解决方式: 1,每运算出一位,不要打印,先存储。需要容器。 */ public static String toHex(int num) { //1,定义容器。存储的是字符,长度为8.一个整数最多8个16进制位。 char[] chs = new char[8]; //2,定义一个用于操作数组的索引。 int index = chs.length-1; for(int x=0; x<8; x++) { int temp = num & 15; if(temp > 9) chs[index] = ((char)(temp-10+'A')); else chs[index] = ((char)(temp+'0')); index--; num = num >>> 4; } /*//4,遍历数组。 for(int x=0; x<chs.length; x++) { System.out.print(chs[x]+","); } */ return "0x"+toString(chs); } //定义一个功能,将字符数组转成字符串。 public static String toString(char[] arr) { String temp = ""; for(int x=0; x<arr.length; x++) { temp = temp + arr[x]; } return temp; } }
class ArrayTest6 { public static void main(String[] args) { int num = 60; String str_hex = toHex(num); System.out.println(str_hex); } /* 需求:十进制-->十六进制。 &15 >>>4 循环 遇到问题: 1,顺序反了。2,去除多余的0. 解决方式: 1,每运算出一位,不要打印,先存储。需要容器。 2,去除零?需要转换的数据会不断的右移,如果右移后剩余的二进制都是0,也就是没有有效位, 就不需要进行&运算了。也就是不需要在往数组中存储了。 */ public static String toHex(int num) { //1,定义容器。存储的是字符,长度为8.一个整数最多8个16进制位。 char[] chs = new char[8]; //2,定义一个用于操作数组的索引。 int index = chs.length; while(num!=0) { int temp = num & 15; if(temp > 9) chs[--index] = ((char)(temp-10+'A')); else chs[--index] = ((char)(temp+'0')); num = num >>> 4; } System.out.println("index="+index); return "0x"+toString(chs,index); } //定义一个功能,将字符数组转成字符串。 public static String toString(char[] arr,int index) { String temp = ""; for(int x=index; x<arr.length; x++) { temp = temp + arr[x]; } return temp; } }
class ArrayTest7 { public static void main(String[] args) { int num = 26; String str_hex = toHex(num); System.out.println("hex:"+str_hex); } /* 需求;十进制-->十六进制,终结版。 思路: 十进制转成十六进制的每一位都是十六进制元素中的某一个。 十六进制的元素有很多固定个数。而且还有对应的编号。 所以可以使用传说中的 查表法! */ public static String toHex(int num) { //1,建立表。 char[] chs = {'0','1','2','3' ,'4','5','6','7' ,'8','9','A','B' ,'C','D','E','F'}; //2,创建临时容器。 char[] arr = new char[8]; //3,创建操作临时容器的角标。 int index = arr.length; //4,通过循环对num进行& >>等运算。 while(num!=0) { //5,对num进行&运算。 int temp = num & 15; //6,根据&运算后的结果作为角标查表,获取对应的字符。并将字符存储到临时容器中。 arr[--index] = chs[temp]; //7,对num进行右移。 num = num >>> 4; } return "0x"+toString(arr,index); } //定义一个功能,将字符数组转成字符串。 public static String toString(char[] arr,int index) { String temp = ""; for(int x=index; x<arr.length; x++) { temp = temp + arr[x]; } return temp; } }
class ArrayTest8 { public static void main(String[] args) { int num = 60; String str_bin = toBinary(num); String str_oct = toOctal(num); String str_hex = toHex(num); System.out.println("bin:"+str_bin); System.out.println("oct:"+str_oct); System.out.println("hex:"+str_hex); //Java已经提供的功能。 System.out.println(Integer.toBinaryString(60)); System.out.println(Integer.toOctalString(60)); System.out.println(Integer.toHexString(60)); } /* 十进制-->十六进制。 */ public static String toHex(int num) { return "0x"+trans(num,15,4); } /* 十进制-->二进制。 */ public static String toBinary(int num) { return trans(num,1,1); } /* 十进制-->八进制。 */ public static String toOctal(int num) { return "0"+trans(num,7,3); } //用于进制转换。 public static String trans(int num,int base,int offset) { if(num==0) return "0"; //1,建立表。 char[] chs = {'0','1','2','3' ,'4','5','6','7' ,'8','9','A','B' ,'C','D','E','F'}; //2,创建临时容器。 char[] arr = new char[32]; //3,创建操作临时容器的角标。 int index = arr.length; //4,通过循环对num进行& >>等运算。 while(num!=0) { //5,对num进行&运算。 int temp = num & base; //6,根据&运算后的结果作为角标查表,获取对应的字符。并将字符存储到临时容器中。 arr[--index] = chs[temp]; //7,对num进行右移。 num = num >>> offset; } return toString(arr,index); } //定义一个功能,将字符数组转成字符串。 public static String toString(char[] arr,int index) { String temp = ""; for(int x=index; x<arr.length; x++) { temp = temp + arr[x]; } return temp; } }
3、数组排序
import java.util.Arrays; class ArrayTest9 { public static void main(String[] args) { int[] arr = {12,9,23,77,6,34}; printArray(arr); //selectSort(arr); // bubbleSort(arr); // Arrays.sort(arr);//开发时用这个。 printArray(arr); } //打印数组的方法。 public static void printArray(int[] arr) { for(int x=0; x<arr.length; x++) { if(x!=arr.length-1) System.out.print(arr[x]+","); else System.out.println(arr[x]); } } /* 数组的排序。 选择排序。 */ public static void selectSort(int[] arr) { for(int x=0 ;x<arr.length-1; x++) { for(int y=x+1; y<arr.length; y++) { if(arr[x]>arr[y]) { // int temp = arr[x]; // arr[x] = arr[y]; // arr[y] = temp; swap(arr,x,y); } } } } /* 冒泡排序。 */ public static void bubbleSort(int[] arr) { for(int x=0; x<arr.length-1; x++) { for(int y=0; y<arr.length-1-x; y++) { if(arr[y]>arr[y+1]) { // int temp = arr[y]; // arr[y] = arr[y+1]; // arr[y+1] = temp; swap(arr,y,y+1); } } } } //发现排序方法,位置置换代码重复,进行抽取。 public static void swap(int[] arr,int a,int b) { int temp = arr[a]; arr[a] = arr[b]; arr[b] = temp; } }
class ArrayTest10 { public static void main(String[] args) { int[] arr = {9,12,15,24,36,41,59,68}; int index = binarySearch(arr,45); System.out.println("index="+index); } //二分查找。前提:数组必须是有序的。 /* 思路: 1,通过角标先获取中间角标上元素。 2,让该元素和要找的数据比较。 3,如果要找的数大了,缩小范围,要找的范围应该是 中间的角标+1---尾角标。 如果要找的数小了,要找的范围 头角标---中间角标-1; 4,不断如此重复,就可以找到元素对应的角标。 */ public static int binarySearch(int[] arr,int key) { //1,定义三个变量,记录头角标,尾角标,中间角标。 int max,min,mid; min = 0; max = arr.length-1; mid = (max+min)>>1; while(arr[mid]!=key) { if(key>arr[mid]) min = mid + 1; else if(key<arr[mid]) max = mid - 1; //判断元素是否存在。 if(max<min) return -1; mid = (max+min)>>1; } return mid; } public static int binarySearch(int[] arr,int key) { //1,定义三个变量,记录头角标,尾角标,中间角标。 int max,min,mid; min = 0; max = arr.length-1; while(min<=max) { mid = (min+max)>>1; if(key>arr[mid]) min = mid + 1; else if(key<arr[mid]) max = mid - 1; else return mid; } return -1; } //查找。 /* 需求;查找一个元素在数组中的第一次出现的位置。 */ public static int searchKey(int[] arr,int key) { //遍历查找。 for(int x=0; x<arr.length; x++) { if(arr[x]==key) return x; } return -1;//-1,代表的是角标不存在的情况。 } }
4、二维数组
class Array2Demo { public static void main(String[] args) { //二维数组。 /* int[][] arr = new int[3][2]; System.out.println(arr);// [[I@e6f7d2//二维数组实体。 System.out.println(arr[0]);//[I@3e0ebb//一维数组实体。 System.out.println(arr[0][0]);//0 一维数组中的元素。 */ // int[][] array = new int[3][];//明确了二维数组的长度,没有明确具体的一维数组。 System.out.println(array);//[[I@3e0ebb System.out.println(array[0]);//null System.out.println(array[0][0]);//NullPointerException } }
class Array2Demo2 { public static void main(String[] args) { /* 二维数组的另一种定义方式。 */ int[][] arr = {{23,17,11},{88,11,33,90},{11,78,34}}; //求和。 int sum = 0; for(int x=0; x<arr.length; x++)//遍历二维数组 { for(int y=0; y<arr[x].length; y++) { sum+=arr[x][y]; } } System.out.println("sum="+sum); } }
二维数组内存图
5、小练习
/* 前五天,阶段要点: path classpath配置 常见的编译错误提示。以及解决办法。 ------- ++ &,&&的区别。 位运算 & >>> 循环嵌套。相关练习,一定要写思路。 函数的两个明确。 数组,查表法的应用。 数组的常见的应用和操作编程题一定要练。 画图: 1,函数调用的执行流程。 2,数组在内存中的分布。 3,理解题,栈,堆的特点。 阶段综合练习:进制转换。 */ import java.util.Arrays; class Test { public static void main(String[] args) { int[] arr = {9,13,17,22,31,46,58,77}; int index = binarySearch(arr,7); int index2 = Arrays.binarySearch(arr,7); System.out.println("index="+index); System.out.println("index2="+index2); } /* 对一个给定的数组进行反转。 {23,14,88,5} -> {5,88,14,23} */ public static void reverse(int[] arr) { for(int start=0,end=arr.length-1; start<end; start++,end--) { swap(arr,start,end); } } public static void swap(int[] arr,int a,int b) { int temp = arr[a]; arr[a] = arr[b]; arr[b] = temp; } /* 思考题! 需求:如果往有序的数组中插入一个元素并继续保证有序,问如何获取该位置? 思路: 1,既然是有序的数组,而且是找位置,必须要想到 二分查找法。 */ public static int binarySearch(int[] arr,int key) { int max,min,mid; min = 0; max = arr.length-1; while(min<=max) { mid = (min+max)>>1; if(key>arr[mid]) min = mid + 1; else if(key<arr[mid]) max = mid - 1; else return mid; } return -(1+min); } }
6、代码清单
day05代码清单:
ArrayTest3.java : 将数组转成字符串。
ArrayTest4.java : 查表法,星期示例。
ArrayTest5.java : 十六进制转换,解决了顺序反的问题。使用的数组。
ArrayTest6.java : 十六进制转换,解决了去零问题。
ArrayTest7.java : 十六进制转换,使用了查表法。
ArrayTest8.java : 三种进制转换,通用版。综合练习。★★★★★
ArrayTest9.java : 选择和冒泡排序。
ArrayTest10.java : 普通查找和二分查找。
Array2Demo.java : 二维数组演示,要画图。
Array2Demo2.java : 二维数组的求和。
Test.java : 数组的反转。有序数组的插入点。