数组
  cA1FqmrigEPj 12天前 36 0

数值型数组特征值统计:

简单示例:

求总和与均值:

给定数组arr = {4,5,6,1,9},求其总和、平均值并输出。

求解代码:

public class Test {
    public static void main(String[] args) {
        int[] arr = {4,5,6,1,9};
        //求总和、均值
        int sum = 0;//因为0加上任何数都不影响结果
        for(int i=0; i<arr.length; i++){
            sum += arr[i];//求总和
        }
        double avg = (double)sum/arr.length;//求平均值

        System.out.println("sum = " + sum);//输出总和
        System.out.println("avg = " + avg);//输出平均值
    }
}

 最大最小值:

给定数组arr = {4,5,6,1,9},求其最大最小值并输出。

求解代码:

public class Test {
    public static void main(String[] args) {
        int[] arr = {4,5,6,1,9};
        //找最大值
        int max = arr[0];
        //此处i从1开始,若是max则不需要与arr[0]再比较一次了
        for(int i=1; i<arr.length; i++){
            if(arr[i] > max){
                max = arr[i];
            }
        }
        int min = arr[0];
        //此处i从1开始,若是min则不需要与arr[0]再比较一次了
        for(int i=1; i<arr.length; i++){
            if(arr[i] < min){
                min = arr[i];
            }
        }
        System.out.println("max = " + max);
        System.out.println("min = " + min);
    }
}

复制、赋值

使用简单数组
(1)创建一个名为ArrayTest的类,在main()方法中声明array1和array2两个变量,他们是int[]类型的数组。
(2)使用大括号{},把array1初始化为8个素数:2,3,5,7,11,13,17,19。
(3)显示array1的内容。
(4)赋值array2变量等于array1,修改array2中的偶索引元素,使其等于索引值(如array[0]=0,array[2]=2)。
(5)打印出array1。

public class ArrayExer04 {
    public static void main(String[] args) {
        //(1)创建一个名为ArrayExer04的类,在main()方法中声明array1和array2两个变量,他们是int[]类型的数组。
        int[] array1,array2;
        //(2)使用大括号{},把array1初始化为8个素数:2,3,5,7,11,13,17,19。
        array1 = new int[]{2,3,5,7,11,13,17,19};
        //(3)显示array1的内容。
        for (int i = 0; i < array1.length; i++) {
            System.out.print(array1[i] + "\t");
        }
        //(4)赋值array2变量等于array1,修改array2中的偶索引元素,使其等于索引值(如array[0]=0,array[2]=2)。
        array2 = array1;
        System.out.println();
        System.out.println(array1);
        System.out.println(array2);

        for (int i = 0; i < array2.length; i++) {
            if(i % 2 == 0){
                array2[i] = i;
            }
        }
        System.out.println();//换行
        //(5)打印出array1。
        for (int i = 0; i < array1.length; i++) {
            System.out.print(array1[i] + "\t");
        }
    }
}

思考:array1和array2是什么关系?
【answer】array1和array2是两个变量,共同指向了堆空间中的同一个数组结构。即二者的地址值相同。

拓展:修改题目,实现array2对array1数组的复制

public class ArrayExer04_1 {
    public static void main(String[] args) {
        //(1)创建一个名为ArrayExer04的类,在main()方法中声明array1和array2两个变量,他们是int[]类型的数组。
        int[] array1,array2;
        //(2)使用大括号{},把array1初始化为8个素数:2,3,5,7,11,13,17,19。
        array1 = new int[]{2,3,5,7,11,13,17,19};
        //(3)显示array1的内容。
        for (int i = 0; i < array1.length; i++) {
            System.out.print(array1[i] + "\t");
        }
        //(4)复制array1数组给array2,修改array2中的偶索引元素,使其等于索引值(如array[0]=0,array[2]=2)。
        array2 = new int[array1.length];
        for (int i = 0; i < array1.length; i++) {
            array2[i] = array1[i];
        }

        System.out.println();
        System.out.println(array1);
        System.out.println(array2);

        for (int i = 0; i < array2.length; i++) {
            if(i % 2 == 0){
                array2[i] = i;
            }
        }

        System.out.println();//换行
        //(5)打印出array1。
        for (int i = 0; i < array1.length; i++) {
            System.out.print(array1[i] + "\t");
        }
    }
}

数组扩容

现有数组 int[] arr = new int[]{1,2,3,4,5};
现将数组长度扩容1倍,并将10,20,30三个数据添加到arr数组中,如何操作?

public class ArrayExer01_1 {
    public static void main(String[] args) {
        int[] arr = new int[]{1,2,3,4,5};

        //扩容1倍容量
//        int[] newArr = new int[arr.length * 2];
        //
        int[] newArr = new int[arr.length << 1];

        //将原有数组中的元素复制到新的数组中
        for (int i = 0; i < arr.length; i++) {

            newArr[i] = arr[i];
        }

        //将10,20,30三个数据添加到新数组中
        newArr[arr.length] = 10;
        newArr[arr.length + 1] = 20;
        newArr[arr.length + 2] = 30;

        //将新的数组的地址赋值给原有的数组变量
        arr = newArr;

        //遍历arr
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + "\t");
        }
    }
}

数组缩容

现有数组 int[] arr={1,2,3,4,5,6,7}。现需删除数组中索引为4的元素。

public class ArrayExer01_2 {
    public static void main(String[] args) {
        int[] arr={1,2,3,4,5,6,7};

        int deleteIndex = 4;

        //方式1:不新建数组
//        for(int i = deleteIndex;i < arr.length - 1;i++){
//            arr[i] = arr[i + 1];
//        }
//
//        //修改最后元素,设置为默认值
//        arr[arr.length - 1] = 0;


        //方式2:新建数组,新的数组的长度比原有数组的长度少1个
        int[] newArr = new int[arr.length - 1];
        for (int i = 0; i < deleteIndex; i++) {
            newArr[i] = arr[i];
        }

        for(int i = deleteIndex;i < arr.length - 1;i++){
            newArr[i] = arr[i + 1];
        }

        arr = newArr;

        //遍历arr数组
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + "\t");
        }

    }
}

 

较难示例:

找出给定数组中包含的最大子数组:

输入一个整形数组,数组里有正数也有负数。数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和。求所有子数组的和的最大值。要求时间复杂度为O(n)。 例如:输入的数组为1, -2, 3, -10, -4, 7, 2, -5,和最大的子数组为3, 10, -4, 7, 2,因此输出为该子数组的和18。

求解代码:

public class Test {
    public static void main(String[] args) {
        int[] arr = new int[]{1, -2, 3, 10, -4, 7, 2, -5};
        int i = getGreatestSum(arr);
        System.out.println(i); // 应输出 18
    }

    public static int getGreatestSum(int[] arr){
        int greatestSum = 0; // 初始化最大和为0
        if(arr == null || arr.length == 0){ // 检查数组是否为空
            return 0; // 如果数组为空,返回0
        }
        int temp = greatestSum; // 初始化临时和为0
        for(int i = 0; i < arr.length; i++){ // 遍历数组
            temp += arr[i]; // 将当前元素加到临时和上
            if(temp < 0){ // 如果临时和小于0,重置为0
                temp = 0;
            }
            if(temp > greatestSum){ // 如果临时和大于最大和,更新最大和
                greatestSum = temp;
            }
        }
        if(greatestSum == 0){ // 如果最大和仍然是0,说明数组中所有元素都是负数
            greatestSum = arr[0]; // 初始化最大和为第一个元素
            for(int i = 1; i < arr.length; i++){ // 再次遍历数组,找到最大的单个元素
                if(greatestSum < arr[i]){ // 如果当前元素大于最大和,更新最大和
                    greatestSum = arr[i];
                }
            }
        }
        return greatestSum; // 返回最大和
    }
}

数组数值赋值:

使用二维数组打印一个10行杨辉三角:

 分析:

  1. 第一行有 1 个元素, 第 n 行有 n 个元素

  2. 每一行的第一个元素和最后一个元素都是 1

  3. 从第三行开始, 对于非第一个元素和最后一个元素的元素。即:

 yanghui[i][j] = yanghui[i-1][j-1] + yanghui[i-1][j];

求解代码:

public class Test {
    public static void main(String[] args) {
        //1. 动态初始化的方式创建二维数组
        int[][] yangHui = new int[10][];
        for (int i = 0; i < yangHui.length; i++) {
            yangHui[i] = new int[i + 1];
            //2. 给数组元素赋值
            // 2.1 给外层数组元素中的首元素和末元素赋值
            yangHui[i][0] = yangHui[i][i] = 1;
            //2.2 给外层数组元素中的非首元素和非末元素赋值(难)
            //非首元素和非末元素的角标范围
            for(int j = 1;j < yangHui[i].length - 1;j++){ 
                yangHui[i][j] = yangHui[i-1][j-1] + yangHui[i-1][j];
            }
        }
        //3. 遍历二维数组
        for (int i = 0; i < yangHui.length; i++) {
            for (int j = 0; j < yangHui[i].length; j++) {
                System.out.print(yangHui[i][j] + "\t");
            }
            System.out.println();
        }
    }
}

生成一个数组:

创建一个长度为6的int型数组,要求数组元素的值都在1-30之间,且是随机赋值。同时,要求元素的值各不相同。

求解代码:

public class Test {
    public static void main(String[] args) {
            int[] arr = new int[6];
            for (int i = 0; i < arr.length; i++) {
                arr[i] = new Random().nextInt(1,30);
                for (int j = 0; j < i; j++) {
                    if (arr[i] == arr[j]) {
                        i--;
                        break;
                    }
                }
            }
            for (int i = 0; i < arr.length; i++) {
                System.out.println(arr[i]);
            }
    }
}

回形数

从键盘输入一个整数(1~20) ,则以该数字为矩阵的大小,把1,2,3…n*n 的数字按照顺时针螺旋的形式填入其中。

例如:

输入数字2,则程序输出:

1 2

4 3

输入数字3,则程序输出:

1 2 3

8 9 4

7 6 5

输入数字4, 则程序输出:

1  2       3  4

12 13    14   5

11    16      15      6

10    9        8        7 

实现代码:

方式一:

public class Test {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.println("输入一个数字");
        int len = scanner.nextInt();
        int[][] arr = new int[len][len];
        int s = len * len;
        /*
         * k = 1:向右
         * k = 2:向下
         * k = 3:向左
         * k = 4:向上
         */
        int k = 1;
        int i = 0,j = 0;
        for(int m = 1;m <= s;m++){
            if(k == 1){
                if(j < len && arr[i][j] == 0){
                    arr[i][j++] = m;
                }else{
                    k = 2;
                    i++;
                    j--;
                    m--;
                }
            }else if(k == 2){
                if(i < len && arr[i][j] == 0){
                    arr[i++][j] = m;
                }else{
                    k = 3;
                    i--;
                    j--;
                    m--;
                }
            }else if(k == 3){
                if(j >= 0 && arr[i][j] == 0){
                    arr[i][j--] = m;
                }else{
                    k = 4;
                    i--;
                    j++;
                    m--;
                }
            }else if(k == 4){
                if(i >= 0 && arr[i][j] == 0){
                    arr[i--][j] = m;
                }else{
                    k = 1;
                    i++;
                    j++;
                    m--;
                }
            }
        }
        //遍历
        for(int m = 0;m < arr.length;m++){
            for(int n = 0;n < arr[m].length;n++){
                System.out.print(arr[m][n] + "\t");
            }
            System.out.println();
        }
    }
}

方式二:

public class Test {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.println("输入一个数字");
        int n = scanner.nextInt();
        int[][] arr = new int[n][n];
        //要显示的数据
        int count = 0;
        //x轴的最大下标
        int maxX = n-1;
        //Y轴的最大下标
        int maxY = n-1;
        //x轴的最小下标
        int minX = 0;
        //Y轴的最小下标
        int minY = 0; 
        while(minX<=maxX) {
            for(int x=minX;x<=maxX;x++) {
                arr[minY][x] = ++count;
            }
            minY++;
            for(int y=minY;y<=maxY;y++) {
                arr[y][maxX] = ++count;
            }
            maxX--;
            for(int x=maxX;x>=minX;x--) {
                arr[maxY][x] = ++count;
            }
            maxY--;
            for(int y=maxY;y>=minY;y--) {
                arr[y][minX] = ++count;
            }
            minX++;
        }
        for(int i=0;i<arr.length;i++) {
            for(int j=0;j<arr.length;j++) {
                String space = (arr[i][j] + "").length()==1 ? "0":"";
                System.out.print(space + arr[i][j] + " ");
            }
            System.out.println();
        }
    }
}

数组数值反转:

数组对称位置的元素互换。

实现代码:

方法一:

public class Test {
    public static void main(String[] args) {
        int[] arr = {1,2,3,4,5};
        System.out.println("反转之前:");
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + "\t");
        }
        System.out.println();
        //反转
         /*
        思路:首尾对应位置的元素交换
        (1)确定交换几次
           次数 = 数组.length / 2
        (2)谁和谁交换
        for(int i=0; i<次数; i++){
             int temp = arr[i];
             arr[i] = arr[arr.length-1-i];
             arr[arr.length-1-i] = temp;
        }
         */
        for(int i=0; i<arr.length/2; i++){
            int temp = arr[i];
            arr[i] = arr[arr.length-1-i];
            arr[arr.length-1-i] = temp;
        }
        System.out.println("反转之后:");
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + "\t");
        }
    }
}

方法二:

public class Test {
    public static void main(String[] args) {
        int[] arr = {1,2,3,4,5};
        System.out.println("反转之前:");
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + "\t");
        }
        System.out.println();
        //反转
        //左右对称位置交换
        for(int left=0,right=arr.length-1; left<right; left++,right--){
            //首  与  尾交换
            int temp = arr[left];
            arr[left] = arr[right];
            arr[right] = temp;
        }
        System.out.println("反转之后:");
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + "\t");
        }
    }
}

字符串反转:

 将字符串转换为字符数组进行反转

写法一:使用char数组,双循环变量

public void test() {
        String str = "abcdefg";
        System.out.println(str);
        char[] strToCharArray = str.toCharArray();
        for (int i = 0, j = strToCharArray.length - 1; i < j; i++, j--) {
            char temp = strToCharArray[i];
            strToCharArray[i] = strToCharArray[j];
            strToCharArray[j] = temp;
        }
        System.out.println();
        str = String.valueOf(strToCharArray);
        System.out.println(str);
    }

写法二:使用char数组,单循环变量

public void test() {
        String str = "abcdefg";
        System.out.println(str);
        char[] strToCharArray = str.toCharArray();
        int half = (int) Math.floor(strToCharArray.length / 2);
        for (int i = strToCharArray.length - 1; i >= half; i--) {
            char temp = strToCharArray[strToCharArray.length - i - 1];
            strToCharArray[strToCharArray.length - i - 1] = strToCharArray[i];
            strToCharArray[i] = temp;
        }
        System.out.println();
        str = String.valueOf(strToCharArray);
        System.out.println(str);
    }

使用异或运算符(^)来实现反转

public void test() {
        String str = "abcdefg";
        System.out.println(str);
        char[] strToCharArray = str.toCharArray();
        int half = (int) Math.floor(strToCharArray.length / 2);
        for (int i = 0; i < half; i++) {
            strToCharArray[i] ^= strToCharArray[strToCharArray.length - i - 1];
            strToCharArray[strToCharArray.length - i - 1] ^= strToCharArray[i];
            strToCharArray[i] ^= strToCharArray[strToCharArray.length - i - 1];
        }
        System.out.println();
        str = String.valueOf(strToCharArray);
        System.out.println(str);
    }

使用StringBuilder类的reverse()来实现反转

 public void test() {
        String str = "abcdefg";
        StringBuilder stringBuilder = new StringBuilder(str);
        System.out.println(stringBuilder);
        String s = String.valueOf(stringBuilder.reverse());
        System.out.println(s);
    }

 排序:

冒泡排序:

使用冒泡排序,实现整型数组元素的排序操作

比如:int[] arr = new int[]{34,54,3,2,65,7,34,5,76,34,67};

public class BubbleSortTest {
    public static void main(String[] args) {
        int[] arr = new int[]{34,54,3,2,65,7,34,5,76,34,67};

        //遍历
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + "\t");
        }

        //冒泡排序,实现数组元素从小到大排列
        for(int j = 0;j < arr.length - 1;j++){
            for (int i = 0; i < arr.length - 1 - j; i++) {
                if(arr[i] > arr[i + 1]){
                    //交互arr[i] 和 arr[i + 1]
                    int temp = arr[i];
                    arr[i] = arr[i + 1];
                    arr[i + 1] = temp;
                }

            }
        }

        System.out.println();
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + "\t");
        }
    }
}

快速排序:

使用快速排序,实现整型数组元素的排序操作

比如:int[] data = { 9, -16, 30, 23, -30, -49, 25, 21, 30 };

public class QuickSort {
    public static void main(String[] args) {
        int[] data = {9, -16, 30, 23, -30, -49, 25, 21, 30};
        System.out.println("排序之前:");
        for (int i = 0; i < data.length; i++) {
            System.out.print(data[i]+" ");
        }

        quickSort(data);//调用实现快排的方法

        System.out.println("\n排序之后:");
        for (int i = 0; i < data.length; i++) {
            System.out.print(data[i]+" ");
        }
    }

    public static void quickSort(int[] data) {
        subSort(data, 0, data.length - 1);
    }

    private static void subSort(int[] data, int start, int end) {
        if (start < end) {
            int base = data[start];
            int low = start;
            int high = end + 1;
            while (true) {
                while (low < end && data[++low] - base <= 0){
                }
                while (high > start && data[--high] - base >= 0){
                }
                if (low < high) {
                    //交换data数组[low]与[high]位置的元素
                    swap(data, low, high);
                } else {
                    break;
                }
            }
            //交换data数组[start]与[high]位置的元素
            swap(data, start, high);

            //经过代码[start, high)部分的元素 比[high, end]都小

            //通过递归调用,对data数组[start, high-1]部分的元素重复刚才的过程
            subSort(data, start, high - 1);
            //通过递归调用,对data数组[high+1,end]部分的元素重复刚才的过程
            subSort(data, high + 1, end);
        }
    }

    private static void swap(int[] data, int i, int j) {
        int temp = data[i];
        data[i] = data[j];
        data[j] = temp;
    }
}

数组工具类Arrays的使用

public class ArraysTest {
    public static void main(String[] args) {
        //1. boolean equals(int[] a,int[] b):比较两个数组的元素是否依次相等
        int[] arr1 = new int[]{1,2,3,4,5};
        int[] arr2 = new int[]{1,2,3,4,5};
        arr2 = new int[]{1,2,3,5,4};

        System.out.println(arr1 == arr2);

        boolean isEquals = Arrays.equals(arr1,arr2);
        System.out.println(isEquals);//true ---> false

        //2. String toString(int[] a):输出数组元素信息。
        System.out.println(arr1); //[I@776ec8df

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

        //3.void fill(int[] a,int val):将指定值填充到数组之中。
        Arrays.fill(arr1,10);

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

        //4. void sort(int[] a):使用快速排序算法实现的排序
        int[] arr3 = new int[]{34,54,3,2,65,7,34,5,76,34,67};
        Arrays.sort(arr3);

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

        //5. int binarySearch(int[] a,int key):二分查找
        //使用前提:当前数组必须是有序的
        int index = Arrays.binarySearch(arr3,15);
        if(index >= 0){
            System.out.println("找到了,索引位置为:" + index);
        }else{
            System.out.println("未找到");
        }
    }
}

数组的使用中常见的异常:

public class ArrayExceptionTest {
    public static void main(String[] args) {
        // 1. 数组角标越界的异常:
        int[] arr = new int[10];
        //角标的有效范围:0、1、2、...、9
//        System.out.println(arr[10]);
//        System.out.println(arr[-1]);

        // 2. 空指针异常:
        //情况1:
//        int[] arr1 = new int[10];
//
//        arr1 = null;
//
//        System.out.println(arr1[0]);//NullPointerException

        //情况2:
//        int[][] arr2 = new int[3][];
//
////        arr2[0] = new int[10];//此行代码不存在时,下一行代码出现NullPointerException
//
//        System.out.println(arr2[0][1]); //NullPointerException

        //情况3:
//        String[] arr3 = new String[4];
//        System.out.println(arr3[0].toString());//NullPointerException

    }
}

查找:

顺序查找:

public class LinearSearchTest {
    public static void main(String[] args) {
        int[] arr1 = new int[]{34,54,3,2,65,7,34,5,76,34,67};
        int target = 5;
//        target = 15;
        //查找方式:线性查找
        //方式1:
//        boolean isFlag = true;
//        for(int i = 0;i < arr1.length;i++){
//            if(target == arr1[i]){
//                System.out.println("找到了" + target + ",对应的位置为:" + i);
//                isFlag = false;
//                break;
//            }
//        }
//
//        if(isFlag){
//            System.out.println("未找到此元素!");
//        }
        //方式2:
        int i = 0;
        for(;i < arr1.length;i++){
            if(target == arr1[i]){
                System.out.println("找到了" + target + ",对应的位置为:" + i);
                break;
            }
        }
        if(i == arr1.length){
            System.out.println("未找到此元素!");
        }
    }
}

优点:

算法逻辑简单;

缺点:

执行效率低,时间复杂度为O(n);

二分查找:

public class BinarySearchTest {
    public static void main(String[] args) {
        int[] arr2 = new int[]{2,4,5,8,12,15,19,26,37,49,51,66,89,100};
        int target = 5;
//        target = 17;
        int head = 0;//默认的首索引
        int end = arr2.length - 1;//默认的尾索引
        boolean isFlag = false;//判断是否找到了指定元素
        while(head <= end){
            int middle = (head + end) / 2;
            if(target == arr2[middle]){
                System.out.println("找到了" + target + ",对应的位置为:" + middle);
                isFlag = true;
                break;
            }else if(target > arr2[middle]){
                head = middle + 1;
            }else{//target < arr2[middle]
                end = middle - 1;
            }
        }
        if(!isFlag){
            System.out.println("未找到该元素");
        }
    }
}

优点:

执行效率高,时间复杂度为O(logN);

缺点:

逻辑稍复杂,数组必须有序;

【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 12天前 0

暂无评论

推荐阅读
  cA1FqmrigEPj   12天前   36   0   0 算法与数据结构