Java 获取数组区间值,Java数组详解

Java数组详解

1. 数组的定义

数组是相同类型数据的有序集合。

数组描述的是相同类型的若干个数据,按照一定的先后次序排列组合而成。

其中,每一个数据称作一个数组元素,每个数组元素可以通过一个下标来访问它们。

2. 数组声明创建

首先必须声明数组变量,才能在程序中使用数组。下面是声明数组变量的语法:

dataType[] arrayRefVar; //首选的方法

//或

dataType arrayRefVar[]; //效果相同,但不是首选方法

Java语言使用new操作符来创建数组,语法如下:

dataType[] arrayRefVar = new dataType[arraysize];

数组的元素是通过索引访问的,数组索引从0开始。

获取数组长度:arrays.length

3. 三种初始化

静态初始化:

int[] a = {1,2,3};

Man[] mans = {new Man(1,1), new Man(2,2)};

动态初始化

int [] a = new int[2];

a[0] = 1;

a[1] = 2;

数组的默认初始化:

数组是引用类型,它的元素相当于类的实例变量,因此数组一经分配空间,其中的每个元素也被按照实例变量同样的方式被隐式初始化。

4. 下标越界及小结

数组的四个基本特点:

其长度是确定的。数组一旦被创建,它的大小就是不可以改变的。其元素必须是相同类型,不允许出现混合类型。

数组中的元素可以是任何数据类型,包括基本类型和引用类型。

数组变量属引用类型,数组也可以看成是对象,数组中的每个元素相当于该对象的成员变量。数组本身就是对象,Java中对象是在堆中的,因此数组无论保存原始类型还是其他对象类型,数组对象本身是在堆中的。

数组边界:

下标的合法区间:[0, length-1],如果越界就会报错;

ArraylndexOutOfBoundsException:数组下标越界异常!

小结:

数组是相同数据类型(数据类型可以为任意类型)的有序集合

数组也是对象。数组元素相当于对象的成员变量

数组长度的确定的,不可变的。如果越界,则报:ArraylndexOutofBounds

5. 数组的使用

普通for循环

for-each循环

int[] arrays = {1,2,3,4,5};

for(int array : arrays){

System.out.println(array);

}

数组作方法入参

public class Array {

public static void main(String[] args) {

int[] arrays = {1,2,3,4,5};

printArray(arrays);

}

//打印数组元素

public static void printArray(int[] arrays){

for (int i = 0; i < arrays.length; i++) {

System.out.print(arrays[i] + " ");

}

}

}

数组作返回值

public class Array {

public static void main(String[] args) {

int[] arrays = {1,2,3,4,5};

// printArray(arrays);

int[] result = reverse(arrays);

printArray(result);

}

//反转数组

public static int[] reverse(int[] arrays){

int[] result = new int[arrays.length];

for( int i = 0, j = arrays.length-1 ; i< arrays.length ; i++ , j--){

result[j] = arrays[i];

}

return result;

}

//打印数组元素

public static void printArray(int[] arrays){

for (int i = 0; i < arrays.length; i++) {

System.out.print(arrays[i] + " ");

}

}

}

6. 多维数组

多维数组可以看成是数组的数组,比如二维数组就是一个特殊的一维数组,其每一个元素都是一个一维数组。

二维数组

int[][] a = new int[2][5];

解析:以上二维数组a可以看成一个两行五列的数组。

public class erweiArray {

public static void main(String[] args) {

int[][] arrays = {{1,2},{2,3},{3,4},{4,5}};

//遍历二维数组

for (int i = 0; i < arrays.length; i++) {

for (int j = 0; j < arrays[i].length; j++) {

System.out.println(arrays[i][j]);

}

}

}

}

7. Arrays类

数组的工具类java.util.Arrays

由于数组对象本身并没有什么方法可以供我们调用,但API中提供了一个工具类Arrays供我们使用,从而可以对数据对象进行一些基本的操作。

查看JDK帮助文档

Arrays类中的方法都是static修饰的静态方法,在使用的时候可以直接使用类名进行调用布"不用"使用对象来调用(注意:是"不用”而不是"不能")

具有以下常用功能:

给数组赋值:通过fill方法。

对数组排序:通过sort方法,按升序。

比较数组:通过equals方法比较数组中元素值是否相等。

查找数组元素:通过binarySearch方法能对排序好的数组进行二分查找法操作。

import java.util.Arrays;

public class ArraysLei {

public static void main(String[] args) {

int[] a = {1,2,3,4,12345,43,12342,98,1243};

Arrays.sort(a); //数组排序:升序

System.out.println(Arrays.toString(a)); //打印数组元素

Arrays.fill(a,2,4,0); //数组填充

System.out.println(Arrays.toString(a));

}

}

8. 冒泡排序

冒泡排序无疑是最为出名的排序算法之一,总共有八大排序!

08f1307a673c8b606cc89b5fae0ef07c.png

冒泡的代码还是相当简单的,两层循环,外层冒泡轮数,里层依次比较,江湖中人人尽皆知。我们看到嵌套循环,应该立马就可以得出这个算法的时间复杂度为O(n2)。

import java.util.Arrays;

//冒泡排序:

//1.比较数组中,两个相邻的元素,如果第一个数比第二个数大,我们就交换他们的位置;

//2.每一次比较,都会产生出一个最大,或者最小的数字;

//3. 下一轮则可以少一次排序!

//4. 依次循环,直到结束!

public class maopaopaixu {

public static void main(String[] args) {

int[] a = {1,4,5,72,2,2,2,25,6,7};

int[] sort = sort(a); //调用完我们自己写的排序方法以后,返回一个排序后的数组

System.out.println(Arrays.toString(sort));

}

public static int[] sort(int[] array){

//临时变量

int temp = 0;

//外层循环,判断我们这个要走多少次;

for (int i = 0; i < array.length-1; i++) {

//内层循环,比较判断两个数,如果第一个数,比第二个数大,则交换位置

for (int j = 0; j < array.length-1-i; j++) {

if (array[j+1]

temp = array[j];

array[j] = array[j+1];

array[j+1] = temp;

}

}

}

return array;

}

}

思考:如何优化?

import java.util.Arrays;

//冒泡排序:

//1.比较数组中,两个相邻的元素,如果第一个数比第二个数大,我们就交换他们的位置;

//2.每一次比较,都会产生出一个最大,或者最小的数字;

//3. 下一轮则可以少一次排序!

//4. 依次循环,直到结束!

public class maopaopaixu {

public static void main(String[] args) {

int[] a = {1,4,5,72,2,2,2,25,6,7};

int[] sort = sort(a); //调用完我们自己写的排序方法以后,返回一个排序后的数组

System.out.println(Arrays.toString(sort));

}

public static int[] sort(int[] array){

//临时变量

int temp = 0;

//外层循环,判断我们这个要走多少次;

for (int i = 0; i < array.length-1; i++) {

boolean flag = false;

//内层循环,比较判断两个数,如果第一个数,比第二个数大,则交换位置

for (int j = 0; j < array.length-1-i; j++) {

if (array[j+1]

temp = array[j];

array[j] = array[j+1];

array[j+1] = temp;

flag = true;

}

}

if (flag == false){

break;

}

}

return array;

}

}

9. 稀疏数组

当一个数组中大部分元素为0,或者为同一值的数组时,可以使用稀疏数组来保存该数组。

稀疏数组的处理方式是:

记录数组一共有几行几列,有多少个不同值

把具有不同值的元素和行列及值记录在一个小规模的数组中,从而缩小程序的规模

如下图:左边是原始数组,右边是稀疏数组

3fff16279621a80587962e4603b98429.png

例题:

需求:编写五子棋休息中,有存盘退出和续上盘的功能。

9a0eb8012d533c98c8743071cc3c7452.png

分析问题:因为该二维数组的很多值是默认值0,因此记录了很多没有意义的数据。

解决:稀疏数组

public class xishushuzu {

public static void main(String[] args) {

//1. 创建一个二维数组 11*11 0:没有棋子, 1:黑棋 2:白棋

int[][] array1 = new int[11][11];

array1[1][2] = 1;

array1[2][3] = 2;

//输出原始的数组

System.out.println("输出原始的数组");

for (int[] ints : array1) {

for (int anInt : ints) {

System.out.print(anInt+"\t");

}

System.out.println();

}

System.out.println("=====================");

//转换为系数数组保存

//获取有效值的个数

int sum = 0;

for (int i = 0; i < 11; i++) {

for (int j = 0; j < 11; j++) {

if (array1[i][j]!=0){

sum++;

}

}

}

System.out.println("有效值的个数:"+sum);

//2.创建一个稀疏数组的数组

int[][] array2 = new int[sum+1][3];

array2[0][0] = 11;

array2[0][1] = 11;

array2[0][2] = sum;

//遍历二维数组,将非零的值,存放到稀疏数组中

int count = 0;

for (int i = 0; i < array1.length; i++) {

for (int j = 0; j < array1[i].length; j++) {

if(array1[i][j]!=0){

count++;

array2[count][0] = i;

array2[count][1] = j;

array2[count][2] = array1[i][j];

}

}

}

//输出稀疏数组

System.out.println("稀疏数组");

for (int i = 0; i < array2.length; i++) {

System.out.println(array2[i][0]+"\t"

+array2[i][1]+"\t"

+array2[i][2]+"\t");

}

System.out.println("=====================");

System.out.println("还原");

//1.读取稀疏数组

int[][] array3 = new int[array2[0][0]][array2[0][1]];

//2.给其中的元素还原它的值

for (int i = 1; i < array2.length; i++) {

array3[array2[i][0]][array2[i][1]] = array2[i][2];

}

//3.打印

System.out.println("输出还原的数组");

for (int[] ints : array1) {

for (int anInt : ints) {

System.out.print(anInt+"\t");

}

System.out.println();

}

}

}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
树状数组(Fenwick Tree)是一种用于快速维护数组前缀和的数据结构。它可以在 $O(\log n)$ 的时间内完成单点修改和前缀查询操作,比线段树更加简洁高效。 下面是 Java 实现的树状数组详解: 首先,在 Java 中我们需要使用数组来表示树状数组,如下: ``` int[] tree; ``` 接着,我们需要实现两个基本操作:单点修改和前缀查询。 单点修改的实现如下: ``` void update(int index, int value) { while (index < tree.length) { tree[index] += value; index += index & -index; } } ``` 该函数的参数 `index` 表示要修改的位置,`value` 表示修改的。在函数内部,我们使用了一个 `while` 循环不断向上更新树状数组中相应的节点,直到到达根节点为止。具体来说,我们首先将 `tree[index]` 加上 `value`,然后将 `index` 加上其最后一位为 1 的二进制数,这样就可以更新其父节点了。例如,当 `index` 为 6 时,其二进制表示为 110,最后一位为 2^1,加上后变为 111,即 7,这样就可以更新节点 7 了。 前缀查询的实现如下: ``` int query(int index) { int sum = 0; while (index > 0) { sum += tree[index]; index -= index & -index; } return sum; } ``` 该函数的参数 `index` 表示要查询的前缀的结束位置,即查询 $[1, index]$ 的和。在函数内部,我们同样使用了一个 `while` 循环不断向前查询树状数组中相应的节点,直到到达 0 为止。具体来说,我们首先将 `sum` 加上 `tree[index]`,然后将 `index` 减去其最后一位为 1 的二进制数,这样就可以查询其前一个节点了。例如,当 `index` 为 6 时,其二进制表示为 110,最后一位为 2^1,减去后变为 100,即 4,这样就可以查询节点 4 的了。 最后,我们还需要初始化树状数组,将其全部置为 0。初始化的实现如下: ``` void init(int[] nums) { tree = new int[nums.length + 1]; for (int i = 1; i <= nums.length; i++) { update(i, nums[i - 1]); } } ``` 该函数的参数 `nums` 表示初始数组。在函数内部,我们首先创建一个长度为 `nums.length + 1` 的数组 `tree`,然后逐个将 `nums` 中的元素插入到树状数组中。具体来说,我们调用 `update(i, nums[i - 1])` 来将 `nums[i - 1]` 插入到树状数组的第 `i` 个位置。 到此为止,我们就完成了树状数组的实现。可以看到,树状数组的代码比线段树要简洁很多,而且效率也更高。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值