数组概述
2、数组变量属引用类型,数组也可以看成是对象,数组中的每个元素相当于该对象的成员变量。
3、数组中的元素可以是任何类型,包括基本类型和引用类型。
一维数组的声明:
1、一维数组的声明方式:
type var[]; 或type[] var;
例如:int a1[]; int[] a2; double b[]; Person[] p1; String s1[];
2、java语言中声明数组时不能指定其长度(数组中元素的个数),例如:int a[5]; //非法
一维数组对象的创建:
1、java中使用关键字new 创建数组对象,格式为:数组名 = new 数组元素类型[数组元素个数];
public class TestArray{
public static void main(String args[]){
int[] arr;
arr = new int[5];
for(int i=0;i<5;i++){
arr[i] = i;
System.out.println(arr[i]);
}
}
}
2、元素为引用类型的数据(注意:元素为引用数据类型的数组中的每一个元素都需要实例化)
public class TestArray{
public static void main(String args[]){
Date[] date;
date = new Date[3];
for(int i=0; i<3; i++){
date[i] = new Date(2014,10,25);
System.out.println(date[i].year+"年,"+date[i].month+"月,"+date[i].day+"日!");
}
}
}
class Date{
int year,month,day;
public Date(int year,int month,int day){
this.year = year;
this.month = month;
this.day = day;
}
}
一维数组初始化:
1、动态初始化:
数组定义与为数组元素分配空间和赋值的操作分开进行,例如:
public class TestArray{
public static void main(String args[]){
int[] arr = new int[3]; //数组定义
arr[0]=1; //数组初始化
arr[1]=2;
arr[2]=3;
Date[] date = new Date[3]; //数组定义
date[0] = new Date(2014,10,25); //数组初始化
date[1] = new Date(2014,10,25);
date[2] = new Date(2014,10,25);
}
}
class Date{
int year,month,day;
public Date(int year,int month,int day){
this.year = year;
this.month = month;
this.day = day;
}
}
2、静态初始化
在定义数组的同时就为数组元素分配空间并赋值,例如:
public class TestArray{
public static void main(String args[]){
int a[] = {1,2,3};
Date[] date = {new Date(2014,10,25), new Date(2014,10,26), new Date(2014,10,27)};
}
}
class Date{
int year,month,day;
public Date(int year,int month,int day){
this.year = year;
this.month = month;
this.day = day;
}
}
3、数组元素的默认初始化:
数组时引用类型,它的元素相当于类的成员变量,因此数组分配空间后,每个元素也被按照成员变量的规则被隐式初始化,
public class TestArray{
public static void main(String args[]){
int[] a = new int[3];
Date[] date = new Date[3];
System.out.println(a[2]);
System.out.println(date[2]);
}
}
class Date{
int year,month,day;
public Date(int year,int month,int day){
this.year = year;
this.month = month;
this.day = day;
}
}
接下来,我们用数组实现一个简单的二分法查找算法
public class TestSearch{
public static void main(String args[]){
int[] a = {12,23,41,53,24,57,32,52,98,43,19,73};
int postion = binarySearch(a,57);
System.out.println(postion);
}
public static int binarySearch(int[] a, int searchNum){
if(a.length==0)return -1;
int startFlag = 0;
int endFlag = a.length-1;
int m = (startFlag+endFlag)/2;
while(startFlag<=endFlag){
if(a[m] == searchNum){
return m;
}else if(a[m]<searchNum){
startFlag = m+1;
}else if(a[m]>searchNum){
startFlag = m+1;
}
m = (startFlag+endFlag)/2;
}
return -1;
}
}
二维数组:
1、二维数组可以看成是以数组为元素的数组。例如:int a[][] = {{1,2},{3,4,5,6},{7,8,9}};
2、java中多维数组的声明和初始化应按从高维到低维的顺序进行,例如:int a[][] = new int[3][];
a[0] = new int[2];a[1] = new int[4];a[2] = new int[3];int t1[][] = new int[][4];//这种声明是非法的
二维数组初始化
1、静态初始化:int intA[][] = {{1,2},{2,3},{3,4,5}};int intB[3][2] = {{1,2},{,2,3},{4,5}};//非法声明方式
2、动态初始化:int a[][] = new int[3][5];int b[][] = new int[3][];b[0] = new int[2];b[1] = new int[3];b[2] = new int[5];
public class Test{
public static void main(String args[]){
int a[][] = {{1,2},{3,4,5,6},{7,8,9}};
for(int i=0; i<a.length; i++){
for(int j=0; j<a[i].length; j++){
System.out.print("["+i+"]"+"["+j+"]="+a[i][j]+" ");
}
System.out.println();
}
}
}
二维数组举例(引用类型的二维数组):
public class Test{
public static void main(String args[]){
String s[][];
s = new String[3][];
s[0] = new String[2];
s[1] = new String[3];
s[2] = new String[2];
for(int i=0; i<s.length; i++){
for(int j=0; j<s[i].length; j++){
s[i][j] = new String("我的位置是:"+i+","+j);
}
System.out.println();
}
for(int i=0; i<s.length; i++){
for(int j=0; j<s[i].length; j++){
System.out.print(s[i][j]+" ");
}
System.out.println();
}
}
}
数组的拷贝:
1、使用java.lang.system类的静态方法
public static void arrayCopy(object src,int srcPos,object dest,int destPos,int length){}
2、可以用于数组src从第srcPos项元素开始的length个元素拷贝到目标数组从destPos项开始的lenght个元素。
3、如果源数据数目超过目标数组边界会抛出IndexOutOfBoundsException异常。
数据拷贝举例:
import java.lang.System;
public class TestArrayCopy{
public static void main(String args[]){
String[] s = {"Microsoft","IBN","Sun","Oracle","Apple"};
String[] sBak = new String[6];
System.arraycopy(s,0,sBak,0,s.length);
for(int i=0;i<sBak.length;i++){
System.out.print(sBak[i]+" ");
}
System.out.println();
int[][] intArray = {{1,2},{1,2,3},{3,4}};
int[][] intArrayBak = new int[3][];
System.arraycopy(intArray,0,intArrayBak,0,intArray.length);
intArrayBak[2][1] = 100;
for(int i=0;i<intArray.length;i++){
for(int j=0;j<intArray[i].length;j++){
System.out.print(intArray[i][j]+" ");
}
System.out.println();
}
}
}
数组的介绍告终,接下来演示一下数组在数据结构中的应用(稀疏矩阵压缩存储)
基本介绍
当一个数组中大部分元素为0,或者为同一个值的数组时,可以使用稀疏数组来保存该数组。
稀疏数组的处理方法
- 记录数组一共有几行几列,有多少个不同的值
- 把具有不同值的元素的行列及值记录在一个小规模的数组中,从而缩小程序的规模
- 具体思路如下:
public class Main {
public static void main(String[] args) {
//先创建一个原始的二维数组
//0,表示没有棋子,1表示黑子,2表示蓝子
int [][]chessArr1=new int[11][11];
chessArr1[1][2]=1;
chessArr1[2][3]=2;
System.out.println("原始的二维数组");
for (int[] row : chessArr1) {
//二维数组循环得到的是一个一维数组
for (int data : row) {
//遍历一维数组,格式化输出
System.out.printf("%d\t",data);
}
System.out.println();
}
//开始转换
//1.先遍历二维数组,得到非0元素的个数
int sum=0;
for(int i=0;i<chessArr1.length;i++) {
//这里的chessArr1.length得到的是二维数组的行
for(int j=0;j<chessArr1[1].length;j++) {
//这里第一行的length表示的是二维数组的列
if(chessArr1[i][j]!=0) {
sum++;
}
}
}
//2.创建对应的稀疏数组,行为sum+1,列一直为3(行,列,值)
int [][]chessArr2=new int[sum+1][3];
//第一行存储的是原始的行数,列数,以及总数据数
chessArr2[0][0]=11;
chessArr2[0][1]=11;
chessArr2[0][2]=sum;
//3.遍历二位数组,把非零的值存放到稀疏数组中
int count=0;//count用来记录第几个非0数据
for(int i=0;i<chessArr1.length;i++) {
for(int j=0;j<chessArr1[1].length;j++) {
if(chessArr1[i][j]!=0) {
count++;//因为第0行已经存放了
chessArr2[count][0]=i;
chessArr2[count][1]=j;
chessArr2[count][2]=chessArr1[i][j];
}
}
}
//输出稀疏数组,因为这里列比较固定,就不用二维数组了
System.out.println("转换后的稀疏矩阵");
for(int i=0;i<chessArr2.length;i++) {
System.out.println(chessArr2[i][0]+"\t"+chessArr2[i][1]+"\t"+chessArr2[i][2]);
}
//恢复,将稀疏数组恢复成原始数组
int [][]chessArr3=new int[chessArr2[0][0]][chessArr2[0][1]]; //chessArr2[0][0]存储的是原始数组的行,//chessArr2[0][1]存储的是原始数组的列
for(int i=1;i<chessArr2.length;i++) {
//这里第0行就不用遍历了
chessArr3[chessArr2[i][0]][chessArr2[i][1]]=chessArr2[i][2];
}
System.out.println("恢复后的二维数组");
for (int[] row : chessArr3) {
//二维数组循环得到的是一个一维数组
for (int data : row) {
//遍历一维数组,格式化输出
System.out.printf("%d\t",data);
}
System.out.println();
}
}
}
结果如下
拓展
要求,1.在前面的基础上,将稀疏数组保存在磁盘上,比如map.data
2.恢复原来的数组时,读取map.data进行恢复。
【我们都知道,在玩游戏中,我们都有存档退出这一说。所以这个就是我们所说的存档退出。然后下次开启继续游戏】
存档
package com.henu.sparsearray;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
public class SparseArrayWrite {
public static void main(String[] args) throws IOException {
//创建一个原始的二维数组 11*11
//0:表示没有棋子,1表示黑子 2表示蓝字
int chessArr1[][] = new int[11][11];
chessArr1[1][2] = 1;
chessArr1[2][3] = 2;
chessArr1[4][5] = 2;
//输出原始的二维数组
System.out.println("原始的二维数组:");
for (int[] row : chessArr1) {
for (int data : row) {
System.out.printf("%d\t", data);
// System.out.print(data + "\t");
}
System.out.println();
}
//将二维数组 转 稀疏数组的思路
//1.先遍历二维数组,得到非零数据的个数。
int sum = 0;
for (int i = 0; i < 11; i++) {
for (int j = 0; j < 11; j++) {
if (chessArr1[i][j] != 0) {
sum++;
}
}
}
//创建对应的稀疏数组
int[][] sparseArr = new int[sum + 1][3];
//给稀疏数组赋值
sparseArr[0][0] = 11;
sparseArr[0][1] = 11;
sparseArr[0][2] = sum;
//遍历二维数组,将非0的值存放到sparseArr中
int count = 0;//count用于记录第几个非0数据
for (int i = 0; i < 11; i++) {
for (int j = 0; j < 11; j++) {
if (chessArr1[i][j] != 0) {
count++;
sparseArr[count][0] = i;
sparseArr[count][1] = j;
sparseArr[count][2] = chessArr1[i][j];
}
}
}
//保存
BufferedWriter bw = new BufferedWriter(new FileWriter("./data/map.data"));
System.out.println();
System.out.println("进行存档。。。");
for (int i = 0; i < sparseArr.length; i++) {
String s = "" + sparseArr[i][0] + "\t"+ sparseArr[i][1] +"\t" + sparseArr[i][2] +"\t\n";
bw.write(s);
}
bw.close();
}
}
读档
public class SparseArrayRead {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new FileReader("./data/map.data"));
List<String> list = new ArrayList<>();
String s = "";
while ((s = br.readLine()) != null){
list.add(s);
}
int[][] newSparseArrayRead = new int[list.size()][list.size()-1];
String s1 = list.get(0);
String[] split = s1.split("\t");
//先将11 11 3放入数组中
newSparseArrayRead[0][0] = Integer.parseInt(split[0]);
newSparseArrayRead[0][1] = Integer.parseInt(split[1]);
newSparseArrayRead[0][2] = list.size()-1;
//设置count值,进行后面的判断。二维数组的行数。
int count = 0;
for (int i = 1; i < list.size(); i++) {
String str = list.get(i);
String[] strings = str.split("\t");
count ++;
for (int j = 0; j < strings.length; j++) {
newSparseArrayRead[count][j] = Integer.parseInt(strings[j]);
}
}
System.out.println("读取文件后建立的稀疏数组:");
for (int[] ints : newSparseArrayRead) {
for (int anInt : ints) {
System.out.printf("%d\t",anInt);
}
System.out.println();
}
//从二维数组转换为原始数组
//1.先读取稀疏数组的第一行,根据第一行的数据,创建原始的二维数组
int[][] chessArr2 = new int[newSparseArrayRead[0][0]][newSparseArrayRead[0][1]];
//2.在读取稀疏数组后几行的数据(从第二行开始),并赋给原始的二维数组 即可
for (int i = 1; i < newSparseArrayRead.length; i++) {
chessArr2[newSparseArrayRead[i][0]][newSparseArrayRead[i][1]] = newSparseArrayRead[i][2];
}
//输出恢复后的二维数组
System.out.println();
System.out.println("恢复好的二维数组:");
for (int[] row : chessArr2) {
for (int data : row) {
System.out.printf("%d\t",data);
}
System.out.println();
}
br.close();
}
}
全部评论