408考研-数据结构算法-顺序表

news2024/11/19 9:29:59

数组

如何创建数组

我们以 Java 中创建数组为例,创建语法如下

dataType[] arrName = new dataType[size];
  • dataType: 也就是我们数组中元素的数据类型
  • arrName:即数组名
  • size:即数组所能容纳的元素数量
  • new: Java 语言中的关键词

假设我们要创建一个由 10 个元素的数组,其中元素的数据类型为 int,则创建的方法如下

int[] arr = new int[19];

顺序表采用顺序存储方式,即逻辑上相邻的数据在计算机内的存储位置也是相邻的。顺序存储方式,元素存储是连续的,中间不允许有空,可以快速定位第几个元素,但是插入和删除时需要移动大量元素。根据分配空间方法不同,顺序表可以分为静态分配和动态分配两种方法。

静态分配

顺序表最简单的方法是使用一个定长数组data[]存储数据,最大空间为Maxsize,用length记录实际的元素个数,即顺序表的长度。这种用定长数组存储的方法称为静态分配。

在这里插入图片描述

顺序表的静态分配结构体定义,如图2-3所示。采用静态分配方法,定长数组需要预先分配一段固定大小的连续空间,但是在运算的过程中,如合并、插入等操作,容易超过预分配的空间长度,出现溢出。解决静态分配的溢出问题,可以采用动态分配的方法。

动态分配

在程序运行过程中,根据需要动态分配一段连续的空间(大小为Maxsize),用elem记录该空间的基地址(首地址),用length记录实际的元素个数,即顺序表的长度。动态顺序表。采用动态存储方法,在运算过程中,如果发生溢出,可以另外开辟一块更大的存储空间,用以替换原来的存储空间,从而达到扩充存储空间的目的。

在这里插入图片描述
注意哦,这里有两个概念“数组的长度”和“线性表的长度”需要区分一下。

数组的长度是存放线性表的存储空间的长度,存储分配后这个量是一般是不变的。

线性表的长度是线性表中数据元素的个数,随着线性表插入和删除操作的进行,这个量是变化的。

在任意时刻,线性表的长度应该小于等于数组的长度。

数组基本操作

下面分别介绍数组的初始化、创建、取值、查找、插入、删除等基本操作。

1.初始化

初始化是指为顺序表分配一段预定义大小的连续空间,用elem记录这段空间的基地址,当前空间内没有任何数据元素,因此元素的实际个数为0。假设我们已经预定义了一个最大空间数Maxsize,那么就用new分配大小为Maxsize的空间,分配成功会返回空间的首地址,分配失败会返回空指针。

在这里插入图片描述

package com.maweiqi;

public class ArrayDemo {
    public static void main(String[] args) {
        int[] arr = new int[10];
        int length = 0;
        for (int i = 0;i< 5;i++) {
            arr[length++] = i+1;
        }
        System.out.println("数组的容量:"+arr.length);
        System.out.println("数组的长度:"+length);
    }
}

创建数组

顺序表输入数据,输入数据的类型必须与类型定义中的类型一致。

算法步骤

1)初始化下标变量i=0,判断顺序表是否已满,如果是则结束;否则执行第2步。
2)输入一个数据元素x。
3)将数据x存入顺序表的第i个位置,即L.elem[i]=x,然后i++。
4)顺序表长度加1,即L.length++。
5)直到数据输入完毕。

1)输入元素:5。将数据元素5存入顺序表的第0个位置,即L.elem[0]=5,然后i++

在这里插入图片描述
2)输入元素:3。将数据元素3存入顺序表的第1个位置,即L.elem[1]=3,然后i++

在这里插入图片描述
3)输入元素:9。将数据元素9存入顺序表的第2个位置,即L.elem[2]=9,然后i++
在这里插入图片描述

插入元素到数组

在顺序表中第i个位置之前插入一个元素e,需要从最后一个元素开始,后移一位……直到把第i个元素也后移一位,然后把e放入第i个位置

在这里插入图片描述
算法步骤

1)判断插入位置i是否合法(1≤i≤L.length+1),可以在第一个元素之前插入,也可以在第L.length+1个元素之前插入。

2)判断顺序表的存储空间是否已满。

3)将第L.length至第i个元素依次向后移动一个位置,空出第i个位置。

4)将要插入的新元素e放入第i个位置。

5)表长加1,插入成功返回true。

例:顺序表中的第5个位置之前插入一个元素9。

在这里插入图片描述
插入过程如下。

1)移动元素。从最后一个元素(下标为L.length-1)开始后移一位,移动元素过程如下,一共移动四位

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
2)插入元素。此时第5个位置空出来,将要插入的新元素9放入第5个位置,表长加1

在这里插入图片描述

要插入元素到数组中,可以分为如下3 中情况
1.插入数组开头
2.插入数组结尾
3.插入数组中间

package com.maweiqi;

import java.util.Arrays;

public class AddArrDemo {
    /**
     * 将元素插入到中间
     */
    public static int[] insertMid(int[] arr ,int index,int val){
        //创建一个新的数组,用于存放插入的元素
        int[] destArr = new int[arr.length + 1];
        //将原数组插入到元素位置前半段赋值给新数组
        for (int i = 0; i< index; i++) {
            destArr[i] = arr[i];
        }
        //将原数组插入到新数组的后半段
        for (int j = index; j < arr.length; j++) {
            destArr[j+1] = arr[j];
        }
        //将元素插入到新数组的指定位置
        destArr[index] = val;
        return destArr;
    }

    /**
     * 插入元素到数组的结尾
     */
    public static int[] insertEnd(int[] arr ,int val){
        //创建一个新的数组,用于存放插入的元素
        int[] destArr = new int[arr.length + 1];
        //将元素插入到数组的结尾,同时将原数组整体复制到新数组
        destArr[arr.length] = val;
        for (int i = 0; i < arr.length; i++) {
            destArr[i] = arr[i];
        }
        return destArr;
    }

    /**
     * 插入元素到数组的开头
     */
    public static int[] insertStart(int[] arr ,int val){
        //创建一个新的数组,用于存放插入的元素
        int[] destArr = new int[arr.length + 1];
        //将元素插入到数组的开头,同时将原数组整体复制到新数组
        destArr[0] = val;
        for (int i = 0; i < arr.length; i++) {
            destArr[i + 1] = arr[i];
        }
        return destArr;
    }

    public static void main(String[] args) {
        int[] arr = new int[10];
        for (int i = 0;i < arr.length; i++) {
            if(i== 5){
                break;
            }
            arr[i] = i+ 1;
        }
        // [1, 2, 3, 4, 5, 0, 0, 0, 0, 0]
//        System.out.println(Arrays.toString(arr));

//        int[] destArr01 = insertEnd(arr,11);
        //[1, 2, 3, 4, 5, 0, 0, 0, 0, 0, 11]
//         System.out.println(Arrays.toString(destArr01));


//          int[] destArr02 = insertStart(arr,12);
        //[12, 1, 2, 3, 4, 5, 0, 0, 0, 0, 0]
//          System.out.println(Arrays.toString(destArr02));


        int[] destArr03 = insertMid(arr, 3 , 13);
        //[1, 2, 3, 13, 4, 5, 0, 0, 0, 0, 0]
        System.out.println(Arrays.toString(destArr03));
    }
}

删除数组中的元素

在顺序表中删除第i个元素,需要把该元素暂存到变量e中,然后从i+1个元素开始前移……直到把第n个元素也前移一位,即可完成删除操作

在这里插入图片描述
算法步骤

1)判断删除位置i是否合法(1≤i≤L.length)。
2)将欲删除的元素保存在e中。
3)将第i+1至第n个元素依次向前移动一个位置。
4)表长减1,删除成功,返回true。

删除第5个元素。

在这里插入图片描述

删除过程如下。

1)移动元素。首先将待删除元素2暂存到变量e中,以后可能有用,如果不暂存,将会被覆盖。然后从第6个元素开始前移一位,移动元素过程

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

2)表长减1,删除元素后的顺序表如图

在这里插入图片描述

同样的,假设我们要删除数组中的元素,也要考虑如下 3 种情况:

1.删除数组开头元素
2.删除数组末尾元素
3.删除数组中间元素

删除数组开头元素

删除开头元素,相当于将原数组开头元素后边的元素整体向前移动一位,而不用管开头的元素,

package com.maweiqi;

import java.util.Arrays;

public class DeleteArrDemo {

    /**
     *删除数组开头的元素
     */
    public static int[]deleteStart(int[]arr){
        //删除元素后,数组的容量减小
        int[] destArr = new int[arr.length - 1];
        //删除开头的元素,将后面的元素移动到前面
        for (int i = 1;i < arr.length; i++) {
            destArr[i - 1] = arr[i];
        }
        return destArr;
    }
    /**
     *删除数组末尾的元素
     */
    public static int[] deleteEnd(int[] arr){
        //删除元素后,数组的容量减小
        int[] destArr = new int[arr.length - 1];
        //删除末尾的元素
        for (int i = 0;i < arr.length - 1; i++){
            destArr[i] = arr[i];
        }
        return destArr;
    }
    /**
     *删除元素从中间开始删除
     */
    public static int[] deleteMid(int[] arr,int index){
        //删除元素后,数组的容量减小
        int[] destArr = new int[arr.length - 1];
        //删除指定位置元素,前半段保持
        for (int i =0;i < index; i++) {
            destArr[i] = arr[i];
        }
        //后半段整体向前移动一位
        for (int j = index; j < arr.length - 1 ; j++) {
            destArr[j] = arr[j + 1];
        }
        return destArr;
    }

    public static void main(String[] args) {
        int[] arr = new int[10];
        for (int i = 0; i < arr.length; i++) {
            arr[i] = i + 1;
        }
        // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
        System.out.println(Arrays.toString(arr));

        //调用头部开始删除
//        int[] ints = deleteStart(arr);
//      [2, 3, 4, 5, 6, 7, 8, 9, 10]
        //       System.out.println(Arrays.toString(ints));



        //调用从结尾删除数组元素
//         int[] ints = deleteEnd(arr);
         //[1, 2, 3, 4, 5, 6, 7, 8, 9]
//         System.out.println(Arrays.toString(ints));


        //删除中间元素
        int[] ints1 = deleteMid(arr, 3);
//        [1, 2, 3, 5, 6, 7, 8, 9, 10]
        System.out.println(Arrays.toString(ints1));

    }
}

修改数组元素

要修改数组元素,实际上只要知道需要修改数组元素的索引位置即可,然后将对应索引位置的值修改为你要修改的值即可

package com.maweiqi;

import java.util.Arrays;

public class UpdateArrDemo {

    /**
     * 修改数组任意位置元素
     * @param arr 待修改元素的数组
     * @param index 待修改元素索引位置
     * @param val 修改后的元素值
     * @return 修改元素后的数组
     */
    public static int[] update(int[] arr,int index,int val){
        arr[index] = val;
        return arr;
    }

    public static void main(String[] args) {
        int[] arr = new int[10];
        for (int i = 0; i < arr.length; i++) {
            arr[i] = i + 1;
        }
        // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
        System.out.println(Arrays.toString(arr));


        //修改数组任意位置元素
        int[] ints1 = update(arr, 3,100);
//        [1, 2, 3, 5, 6, 7, 8, 9, 10]
        System.out.println(Arrays.toString(ints1));

    }

}



查找数组中的元素

要查找数组中的某一个元素,最常用的方法有如下两种

线性查找,主要针对数组较小时
二分查找,主要针对数组较大时,提高查询效率

线性查找

在顺序表中查找一个元素e,可以从第一个元素开始顺序查找,依次比较每一个元素值。如果相等,则返回元素位置(位序,即第几个元素);如果查找整个顺序表都没找到,则返回-1。例如,下图的顺序表中,查找元素8,查找到其下标为5,返回位序为6。

在这里插入图片描述

线性查找即遍历数组,然后判断各元素是否是目标值,是则输出对应索引位置,否则返回1,此时时间复杂度为O(n);

package com.maweiqi;

public class SearchArrDemo {
    /**
     *查找元素的方法
     */
    public static int linearSearch(int[] array ,int target){
        //查找到目标值时,返回目标索引
        for (int i = 0; i < array.length; i++) {
            if(target == array[i]){
                return i;
            }
        }
        return -1;
    }

    public static void main(String[] args) {
        int[] arr = {2,3,5,7,8,11,15,18};
        int index = linearSearch(arr,7) ;
//        返回的索引为:3
//        找到的值时:7
        System.out.println("返回的索引为:"+index);
        System.out.println("找到的值时:"+arr[index]);
    }
}

二分查找

你小时候或许玩过这样一种猜谜游戏:我心里想着一个1到100之间的数字,在你猜出它之前,我会提示你的答案应该大一点还是小一点。

你应该凭直觉就知道这个游戏的策略。一开始你会先猜处于中间的50,而不是1。为什么?因为不管我接下来告诉你更大或是更小,你都能排除掉一半的错误答案!

如果你说50,然后我提示要再大一点,那么你应该会选75,以排除掉剩余数字的一半。如果在75之后我告诉你要小一点,你就会选62或63。总之,一直都猜中间值,就能不断地缩小一半的范围。

下面来演示这个过程,但仅以1到10为例。

在这里插入图片描述
这就是二分查找的通俗描述。

有序数组相比常规数组的一大优势就是它除了可以用线性查找,还可以用二分查找。常规数组因为无序,所以不可能运用二分查找。

为了看出它的实际效果,假设有一个包含9个元素的有序数组。计算机不知道每个格子的值,如下图所示。

在这里插入图片描述

然后,用二分查找来找出7,过程如下。

第1步:检查正中间的格子。因为数组的长度是已知的,将长度除以2,我们就可以跳到确切的内存地址上,然后检查其值。

在这里插入图片描述

值为9,可推测出7应该在其左边的某个格子里。而且,这下我们也排除了一半的格子,即9右边的那些(以及9本身)。

在这里插入图片描述
第2步:检查9左边的那些格子的最中间那个。因为这里最中间有两个,我们就随便挑了左边的。

在这里插入图片描述

它的值为4,那么7就在它的右边了。由此4左边的格子也就排除了。

在这里插入图片描述

第3步:还剩两个格子里可能有7。我们随便挑个左边的。

在这里插入图片描述
第4步:就剩一个了。(如果还没有,那就说明这个有序数组里真的没有7。)

在这里插入图片描述
终于找到7了,总共4步。是的,这个有序数组要是用线性查找也会是4步,但稍后你就会见识到二分查找的强大。

当数组长度很小时,使用线性查找方法很快就能找到目标值是否存在并返回对应索引位置但当数组很大时,线性查找的方法效率就太低了。这时候二分查找是更理想的查找手段,二分查找实质是使用双指针,每次对半查找,大大提高效率,时间复杂度缩减为o(logn);

package com.maweiqi;

public class BinarySearchDemo {

    //编写二分查找的方法
    public static int binarySearch(int[] array ,int target){
        //左指针和右指针
        int left = 0;
        int right = array.length - 1;
        while (left <= right) {
            //计算mid
            int mid = left + (right - left) / 2;
            //当前值等于目标值,直接返回目标的索引即可
            if(array[mid] == target){
                return mid;
            }else if (array[mid] < target){
                //当前值小于目标值,左指针向右移动一位
                left = mid + 1;
            }else {
                //当前值大于目标值,,右指针向左移动一位
                right = mid - 1;
            }

        }
        return -1;
    }

    public static void main(String[] args) {
        int[] arr = {-1,2,3,5,7,11,18,21,33,56,78,98};
        //2
//        int index = binarySearch(arr,3);
        //-1
        int index = binarySearch(arr,13);
        System.out.println(index);
    }
}

顺序表的优点:操作简单,存储密度高,可以随机存取,只需要O(1)的时间就可以取出第i个元素。

顺序表的缺点:需要预先分配最大空间,最大空间数估计过大或过小会造成空间浪费或溢出。插入和删除操作需要移动大量元素。

在实际问题中,如果经常需要插入和删除操作,则顺序表的效率很低。为了克服该缺点,可以采用链式存储。

二分查找与线性查找区别

对于长度太小的有序数组,二分查找并不比线性查找好多少。但我们来看看更大的数组。

对于拥有100个值的数组来说,两种查找需要的最多步数如下所示。

❏ 线性查找:100步

❏ 二分查找:7步

用线性查找的话,如果要找的值在最后一个格子,或者比最后一格的值还大,那么就得查遍每个格子。有100个格子,就是100步。

二分查找则会在每次猜测后排除掉一半的元素。100个格子,在第一次猜测后,便排除了50个。

再换个角度来看,你就会发现一个规律。

长度为3的有序数组,二分查找所需的最多步数是2。

若长度翻倍,变成7(以奇数为例会方便选择正中间的格子,于是我们把长度翻倍后又增加了一个数),则最多步数会是3。

若再翻倍(并加1),变成15个元素,那么最多步数会是4。

规律就是,每次有序数组长度乘以2,二分查找所需的最多步数只会加1。这真是出奇地高效。

相反,在3个元素的数组上线性查找,最多要3步,7个元素就最多要7步,100个元素就最多要100步,即元素有多少,最多步数就是多少。数组长度翻倍,线性查找的最多步数就会翻倍,而二分查找则只是增加1步。

这种规律可以用下图来展示。

在这里插入图片描述

如果数组变得更大,比如说10000个元素,那么线性查找最多会有10000步,而二分查找最多只有14步。再增大到1000000个元素,则线性查找最多有1000000步,二分查找最多只有20步。

不过还要记住,有序数组并不是所有操作都比常规数组要快。如你所见,它的插入就相对要慢。衡量起来,虽然插入是慢了一些,但查找却快了许多。还是那句话,你得根据应用场景来判断哪种更合适。

总结

关于算法的内容就是这些。很多时候,计算一样东西并不只有一种方法,换种算法可能会极大地影响程序的性能。

同时你还应意识到,世界上并没有哪种适用于所有场景的数据结构或者算法。你不能因为有序数组能使用二分查找就永远只用有序数组。在经常插入而很少查找的情况下,显然插入迅速的常规数组会是更好的选择。

如之前所述,比较算法的方式就是比较各自的步数。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/955833.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于SSM的在线挂号系统java医院预约管理 jsp源代码Mysql

本项目为前几天收费帮学妹做的一个项目&#xff0c;Java EE JSP项目&#xff0c;在工作环境中基本使用不到&#xff0c;但是很多学校把这个当作编程入门的项目来做&#xff0c;故分享出本项目供初学者参考。 一、项目介绍 基于SSM的在线挂号系统 系统有2权限&#xff1a;前台…

基于SSM的服装商城系统【附源码】

【项目特色】 抽奖功能优惠劵功能物流信息功能 简介 基于SSM的服装商城系统 开发语言&#xff1a;Java数据库&#xff1a;MySQL技术&#xff1a;Spring、Mybaits、SpringMVC工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 前台功能:   注册、登录、退出、商品查询、商品列…

Oracle查询语句中做日期加减运算

在Oracle中&#xff0c;可以使用日期函数来实现日期的加减。 若想在日期上加上一定的天数&#xff0c;可以使用"INTERVAL"关键字。例如&#xff0c;如果要将一个日期加上3天&#xff0c;可以使用以下代码&#xff1a; SELECT SYSDATE INTERVAL 3 DAY FROM DUAL; …

【征稿信息】第四届先进材料和智能制造国际学术会议(ICAMIM2023)

第四届先进材料和智能制造国际学术会议&#xff08;ICAMIM2023) 2023 4th International Conference on Advanced Materials and Intelligent Manufacturing 2023年广州市“国际学术会议之都”建设项目— 第四届先进材料和智能制造国际学术会议&#xff08;ICAMIM2023)将于202…

徐涛政治导论:著作串连表格(重点掌握)

考试第一个选择题常考下面的表格&#xff08;很重要&#xff09;

使用vue-pdf出现的卡顿,空白,报错,浏览器崩溃解决办法

如果想直接知道解决办法&#xff0c;请翻到最下面 今天&#xff0c;接到了一个新的需求&#xff0c;我们公司的PDF展示卡住了&#xff0c;导致浏览器直接奔溃。我也刚来公司不久&#xff0c;就去看看是怎么发生的&#xff0c;公司前同事用的vue-pdf&#xff0c;刚开始以为是文…

基于鹈鹕算法优化的BP神经网络(预测应用) - 附代码

基于鹈鹕算法优化的BP神经网络&#xff08;预测应用&#xff09; - 附代码 文章目录 基于鹈鹕算法优化的BP神经网络&#xff08;预测应用&#xff09; - 附代码1.数据介绍2.鹈鹕优化BP神经网络2.1 BP神经网络参数设置2.2 鹈鹕算法应用 4.测试结果&#xff1a;5.Matlab代码 摘要…

QT(8.31)加载资源文件,信号与槽机制

作业&#xff1a; 实现登录界面&#xff0c;设置账号为admin&#xff0c;密码为123456&#xff0c;登陆成功则退出当前界面&#xff0c;切换到其他界面&#xff0c;密码错误或者账号不匹配则清空账号密码输入框中的内容&#xff0c;并输出登录失败&#xff0c;点击取消则退出当…

AIGC爆火,拓世法宝平台上线,打造属于你的专属数字人!

在数字科技的风潮下&#xff0c;短视频已经成为人们日常生活中不可或缺的一部分。中国互联网络信息中心于8月28日发布的第52次《中国互联网络发展状况统计报告》报告显示&#xff0c;截至2023年6月&#xff0c;中国短视频用户已达10.26亿人。在这里面&#xff0c;80后、90后和0…

视觉SLAM与激光SLAM简单对比分析

总述 本文旨在梳理目前较为前沿的SLAM技术&#xff0c;包括激光和视觉&#xff0c;主要从精度和实时性两个方面对算法进系评价。 对于激光SLAM了解不深&#xff0c;后期需要补充相关算法的核心思想与算法框架。有问题请大佬们随时留言&#xff0c;我再改正。 0.1 视觉SLAM算…

vue使用qrcodejs2生成二维码

目录 概要 构建展示的vue组件qrcode.vue 组件的使用 概要 项目中用到需要展示二维码的样式&#xff0c;想到了qrcode 例如&#xff1a; 前提&#xff1a;安装包 npm install qrcodejs2 --save 构建展示的vue组件qrcode.vue <template><div style"width: …

使用spring自带的发布订阅来实现发布订阅

背景 公司的项目以前代码里面有存在使用spring自带发布订阅的代码&#xff0c;因此稍微学习一下如何使用&#xff0c;并了解一下这种实现方式的优缺点。 优点 实现方便&#xff0c;代码方面基本只需要定义消息体和消费者&#xff0c;适用于小型应用程序。不依赖外部中间件&a…

学习高级数据结构:探索平衡树与图的高级算法

文章目录 1. 平衡树&#xff1a;维护数据的平衡与高效性1.1 AVL 树&#xff1a;严格的平衡1.2 红黑树&#xff1a;近似平衡 2. 图的高级算法&#xff1a;建模复杂关系与优化2.1 最小生成树&#xff1a;寻找最优连接方式2.2 拓扑排序&#xff1a;解决依赖关系 拓展思考 &#x1…

el-select下拉多选框 el-select 设置默认值不可删除功能

Element3.0vue3.0 el-select下拉多选框 el-select 设置默认值不可删除功能 Element-UI是一款广泛使用的Vue.js组件库&#xff0c;其中El-Select下拉多选框组件在实际项目开发中经常被使用。然而&#xff0c;在Element 3.0版本中&#xff0c;El-Select下拉多选框默认值可被删除&…

降本56%!纵腾集团搭载OceanBase Cloud开启降本增效新篇章

近日&#xff0c;跨境电商物流领跑企业福建纵腾网络有限公司&#xff08;以下简称“纵腾集团”&#xff09;正式商用原生分布式数据库 OceanBase&#xff0c;为其下专业物流服务“云途物流”提供云数据库支撑服务。目前&#xff0c;已有两大关键业务系统全部接入 OceanBase Clo…

基于JAVAEE技术的ssm校园车辆管理系统源码和论文

基于JAVAEE技术的ssm校园车辆管理系统源码和论文105 开发工具&#xff1a;idea 数据库mysql5.7 数据库链接工具&#xff1a;navcat,小海豚等 技术&#xff1a;ssm 1.选题背景和意义 背景&#xff1a; 随着第二次工业革命后&#xff0c;内燃机的发明与完善&#xff0c;解…

Charles信任证书后依然无法抓包的解决方案

前提 1、Charles安装证书 2、Charles设置SSL代理 3、查看Android安装Charles证书的方法 4、查看Android安装的Charles证书 问题 Charles拦截时&#xff0c;报“SSL handshake with client failed: An unknown issue occurred processing the certificate (certificate_unknow…

Ubuntu20.04安装ROS

Ubuntu20.04安装ROS Excerpt ubuntu安装方式有两种&#xff0c;一种是安装ubuntu系统&#xff0c;另一种是在windows下安装虚拟机&#xff0c;在虚拟机里安装ubuntu。下面为双系统安装ubuntu&#xff08;用虚拟机装ubuntu会很卡&#xff0c;bug很多&#xff0c;除非电脑配置极好…

UI按钮设计原则,让你的产品一次打动用户!

UI按钮是常见的界面组件,广泛应用于表单、对话框以及工具栏等场景。与链接不同,按钮用于让用户执行特定操作,如提交、删除等;而链接则将用户引导到新的页面。优秀的按钮设计能极大地提高用户的操作效率和转化率。本文将全面介绍按钮设计的相关指南,并通过实例解析如何设计出能最…

Android之布局转圆角

Android之布局转圆角 文章目录 Android之布局转圆角说明一、效果图二、实现步骤1.自定义RoundRelativeLayout2.使用 总结 说明 很多需求比较无语&#xff0c;需要某个布局转圆角&#xff0c;像个显眼包一样&#xff0c;所以为了满足显眼包&#xff0c;必须整呐提示&#xff1a…