菜鸟进阶(一)数组

数组概述

1、数组可以看成是多个相同数据类型数据的组合,对这些数据的统一管理。

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,或者为同一个值的数组时,可以使用稀疏数组来保存该数组。

稀疏数组的处理方法

  1. 记录数组一共有几行几列,有多少个不同的值
  2. 把具有不同值的元素的行列及值记录在一个小规模的数组中,从而缩小程序的规模
  3. 具体思路如下:
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();
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值