【Java学习笔记】第三章 数组知识点大全

news2024/11/16 19:30:51

文章目录

  • 3. 数组
    • 3.1 数组的概述
    • 3.2 一维数组的使用
      • 3.2.1 一维数组初始化
      • 3.2.2 一维数组内存解析
    • 3.3 多维数组的使用
      • 3.3.1 多维数组初始化
      • 3.3.2 多维数组的注意事项:
      • 3.3.3 int[] x,y[]
      • 3.3.4 多维数组的内存解析
    • 3.4 数组中涉及到的常见算法
      • 3.4.1 线性查找
      • 3.4.2 二分法查找算法
      • 3.4.3 排序算法
        • 3.4.3.1 十大内部排序算法
        • 3.4.2 算法特点概述
      • 3.4.4 快速排序
        • 快排思想
        • 快排的时间复杂度
          • 1.最好时间复杂度:
          • 2.最坏时间复杂度
          • 3.平均时间复杂度
        • 快排的Java实现:
    • 5. Arrays工具类得使用

3. 数组

3.1 数组的概述

数组(Array),多个相同类型数据按一定顺序排列的集合,通过下标对数组元素进行管理

  • 数组本身是引用数据类型,而数组中的元素可以是基本数据类型或引用数据类型

  • 创建数组对象会在堆中开辟一整块连续的空间,并将这块内存空间的首地址返还给数组名。

  • 数组分类:

    按照维度分类:一维数组,二维数组,…

    按照数据类型分类:基本数据类型元素的数组、引用数据类型元素的数组…

3.2 一维数组的使用

3.2.1 一维数组初始化

数组声明方式:数据类型 数组名[];数据类型[] 数组名;

  • Java语言中声明数组时不能指定其长度(数组中元素的数), 例如: int a[5]; //非法,C++中允许(C++中声明的同时就在堆区开辟空间了,但Java声明只是在栈区开辟空间)

数组初始化方式:

  1. 动态初始化:数组初始化和数组元素赋值分开进行

    int[] arr = new int[3];
    arr[0] = 3;
    arr[1] = 9;
    arr[2] = 8;
    
  2. 静态初始化:数组初始化和数组元素赋值同时进行

    中括号不能写,等号右边可以直接写大括号的内容

    int arr1[] = new int[]{ 3, 9, 8};
    int[] arr2 = {3,9,8};
    

静态初始化中括号内不能写数值

//数组变量声明不需要说明数组长度(因为只是在栈区开辟空间)如
int array[];
//但创建数组变量就需要指明数组长度以便在堆区开辟内存空间
int array1[] = new int[10];//指明10个int类型空间
int array2[] = {1,2,3,4};//也指明要开辟4个int内存空间

数组元素的引用方式:

  • 数组元素下标可以是整型常量或整型表达式。如a[3] , b[i] , c[6*i];

  • 每个数组都有一个属性length指明它的长度,用法

    int array[]={1,2,3};
    System.out.println(array.length);//输出长度
    

数组一旦创建,数组中元素就会被初始化,按数据元素类型不同有不同的初始化方式

  1. 对于基本数据类型而言,默认初始化值各有不同(看下表)
  2. 对于引用数据类型而言,默认初始化值为null(注意与0不同!)

下面时数组元素的默认初始化值:

image-20220806012352451

值得一提的是char的初始值对应的ASCll码值是0,也就是null,但在输出的时候会输出个空格,而空格的ASCll码值是32。引用数据类型如String,该数组输出就是null。

image-20220806012716085

3.2.2 一维数组内存解析

常用内存种类和作用

image-20220806185006928

数组静态声明,动态声明,基本数据类型数组,引用数据类型数组,new开辟空间的内存解析。

image-20220806184914189
  • arr在栈区,存的是数组在堆区开辟的空间的首地址。而new出的数组空间存在堆区,并将首地址值赋给arr,在这里堆区的4个int的初始值是0;

    image-20220927000103100

  • String类型的数组元素初值是null。值得注意的是,并不是将“刘德华”直接赋值,“刘德华”放在字符常量池

3.3 多维数组的使用

多维数组就是数据元素为低维数组,二维数组的数组元素是一维数组,可以理解为一棵树的结构。

二维数组,可以看成是一维数组array1又作为另一个一维数组array2的元素而存在。其实,从数组底层的运行机制来看,其实没有多维数组,都是通过地址来实现高维数组。

3.3.1 多维数组初始化

这里以二维数组为例

image-20220807002418340

3.3.2 多维数组的注意事项:

  • 动态初始化的两种方式区别就在于第二层数组是否有分配空间,并且对于两种动态初始化后数组元素有不同的初值。

    第一种动态初始化第一层数组元素对应的是第二层数组的首地址

    第二种动态初始化第一层元素值为null,不可解引用,具体如下:

    //静态初始化
    int[][] arr=new int[][] {{1,2,3},{4,5}};
    //动态初始化第一种
    int[][] arr2=new int[2][2];
    System.out.println(arr2[0][0]);//输出0
    System.out.println(arr2[0]);//[I@626b2d4a输出的是数组元素的首地址
    
    //动态初始化第二种
    //不同于C++,C++不允许这样的写法,C++必须写明实际所需的空间的大小!
    int[][] arr1=new int[2][];
    System.out.println(arr1[0]);//输出null
    System.out.println(arr1[0][0]);//错误,null无法解引用
    //在堆区实际没给第二层数组分配空间,第一层数组初始值为null
    //java.lang.NullPointerException:Cannot load from int array because "arr1[0]" is null空指针
    
  • 二维数组其他写法

    //括号位置摆放自由
    int[][] arr4=new int[][] {{1,2,3},{4,5}};//正确
    int arr5[][]=new int[][] {{1,2,3},{4,5}};//正确
    int[] arr6[]=new int[][] {{1,2,3},{4,5}};//正确
    
    //类型自动推断,将赋值的内容按照前面个数组声明的类型转换,转不了就报错,如下:
    int[] arr8= {1,2,3};//正确
    int[] arr7[]={{1,2,3},{4,5}};//正确
    int[] arr8[]={{1.2,2,3},{4,5}};//错误,Type mismatch: cannot convert from double to int
    
    //赋值类型要要匹配,不匹配滿足類型提升也行
    double[] arr9 = new double[] {1,2};//正确满足类型提升
    int[] arr10[]={{1.2,2,3},{4,5}};//错误,Type mismatch: cannot convert from double to int
    
    //如果写new,那么数组声明类型和new的类型一定要一致!
    double[] arr11 = new int[2];// 错误,声明是double类型数组,但堆区开辟空间开的是int类型,显然不合理。可以是开辟double的空间,将int赋值进去,这时合理的,如下
    double[] arr12 = {1,2};//正确
    doubele[] arr13 = new double[]{1,2};//正确
    
    //int[] arr8;
    //arr8= {1,2,3}; //分开写错误
    
  • 二维数组动态初始化第二种int[][] arr = new int[3][];,由于数组元素是数组,所以对注意数组元素的赋值方式。此外二维数组第一种动态初始化是内层数组长度一样,二维数组第二种动态初始化是内层数组不一样。

  • 对于一维数组,length就是表示长度。但对于二维数组如:**int[][] arr = new int[][]{{3,8,2},{2,7},{9,0,1,6}};**length就和堆区开辟的空间关系有关系了,arr.length表示arr直接对应的数组的长度(该数组元素为数组),也就是三。如果想查看第二层数组的长度可以arr[0].lenght等等。

3.3.3 int[] x,y[]

x是int型的一维数组,y是int型的二维数组!int[]是一个整体,x是一个整体,y[]是一个整体。

  • x=y 是否合法?

    不合法!虽然都是地址的值但是地址类型有区别

    image-20220809000915533

    注意数组名之际存的是地址值,在做数组复制的时候不要想当然的直接对数组名进行赋值,而是循环遍历赋值。

3.3.4 多维数组的内存解析

image-20220807191731175

3.4 数组中涉及到的常见算法

3.4.1 线性查找

就遍历,略

3.4.2 二分法查找算法

思路总结:对于有序的数组,定义头和尾两个标识,通过比对数组中间的元素和目标元素,每次缩小一半的搜索范围,达到快速检索的目的。实现内部使用三个if语句分类判断。

image-20220811183628214
  • 前提,二分法查找数组元素的前提是一个有序数组!
//二分法查找:要求此数组必须是有序的。
int[] arr3 = new int[]{-99,-54,-2,0,2,33,43,256,999};
boolean isFlag = true;
int number = 256;
//int number = 25;
int head = 0;//首索引位置
int end = arr3.length - 1;//尾索引位置
while(head <= end)
{
	int middle = (head + end) / 2;
	if(arr3[middle] == number)
	{
		System.out.println("找到指定的元素,索引为:" + middle);
		isFlag = false;
		break; 
	}
	else if(arr3[middle] > number)
	{
		end = middle - 1;
	}	
	else
	{
    	//arr3[middle] < number
		head = middle + 1;
	} 	
}
if(isFlag)
{
	System.out.println("未找打指定的元素");
}

3.4.3 排序算法

通常来说,排序的目的是快速查找。

衡量排序算法的优劣:

  1. 时间复杂度:分析关键字的比较次数和记录的移动次数

  2. 空间复杂度:分析排序算法中需要多少辅助内存

  3. 稳定性:若两个记录A和B的关键字值相等,但排序后A、B的先后次序保

持不变,则称这种排序算法是稳定的。

  • 根据是否需要外部存储器,排序算法又分为内部排序和外部排序

排序算法分类:内部排序和外部排序。

  1. 内部排序:整个排序过程不需要借助于外部存储器(如磁盘等),所有排序操作都在内存中完成。

  2. 外部排序:参与排序的数据非常多,数据量非常大,计算机无法把整个排序过程放在内存中完成,必须借助于外部存储器(如磁盘)。外部排序最常见的是多路归并排序。可以认为外部排序是由多次内部排序组成。

3.4.3.1 十大内部排序算法

  1. 选择排序(简单)选择排序
  2. 堆排序堆排序
  3. 冒泡排序冒泡排序
  4. 快速排序快速排序
  5. 直接插入排序(直接)插入排序
  6. 折半插入排序
  7. Shell排序希尔排序
  8. 归并排序归并排序
  9. 桶式排序桶排序
  10. 基数排序基数排序

此外计数排序:计数排序

3.4.2 算法特点概述

image-20220813160405387

3.4.4 快速排序

快速排序

快排思想

  1. 从数列中挑出一个元素,称为"基准"(pivot),

  2. 重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区结束之后,该基准就就将原来的数组分为了两个部分,注意:基准不一定再正中间!这个称为分区(partition)操作。

  3. 递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序。

  4. 递归的最底部情形,是数列的大小是零或一,也就是永远都已经被排序好了。虽然一直递归下去,但是这个算法总会结束,因为在每次的迭代(iteration)中,都会确定一个元素的位置。

image-20220811194231775 image-20220811194241631

快排的时间复杂度

对于长度为n的数组,快排循环一次,确定一个元素的位置。并将数组分为长度分别为I1I2的子数组。

T(n)表示长度为n的数组快排所需的时间复杂度,D(n)=n-1是一趟快排需要的比较次数,一趟快排结束后将数组分成两部分 I1 I2。由递归出以下三种时间复杂度:

1.最好时间复杂度:
  • 就是快排每次划分将数组划分成两个等长子数组I1=I2

设 n 为待排序数组中的元素个数, T(n) 为算法需要的时间复杂度,递归得:
T ( n ) = { D ( 1 ) , n ≤ 1 D ( n ) + T ( I 1 ) + T ( I 2 ) , n > 1 T(n)= \begin{cases} D(1),&n\leq1\\ D(n)+T(I1)+T(I2),&n>1 \end{cases} T(n)={D(1),D(n)+T(I1)+T(I2),n1n>1
所以
T ( n ) = D ( n ) + T ( I 1 ) + T ( I 2 ) = D ( n ) + D ( n 2 ) + D ( n 2 ) + . . . . = n − 1 + 2 ( n 2 − 1 ) + 2 2 ( n 2 2 − 1 ) + . . . + 2 k ( n 2 k − 1 ) = n − 1 + n − 2 + n − 2 2 + . . . n − 2 k ∵ n = 2 k ∴ k = l o g 2 n ∴ T ( n ) = l o g 2 n − 2 n + 1 \begin{aligned} T(n)&=D(n)+T(I1)+T(I2)\\ &=D(n)+D(\frac{n}{2})+D(\frac{n}{2})+....\\ &=n-1+2(\frac{n}{2}-1)+2^2(\frac{n}{2^2}-1)+...+2^k(\frac{n}{2^k}-1)\\ &=n-1+n-2+n-2^2+...n-2^k\\ &\because n=2^k\\ &\therefore k=log_2^n\\ &\therefore T(n)=log_2^n-2n+1 \end{aligned} T(n)=D(n)+T(I1)+T(I2)=D(n)+D(2n)+D(2n)+....=n1+2(2n1)+22(22n1)+...+2k(2kn1)=n1+n2+n22+...n2kn=2kk=log2nT(n)=log2n2n+1

  • 第二种理解:循环一次将数组分为两个子数组,快排结束的条件是所有子数组的元素个数为1。所以确定数组n个元素的位置,每次循环子数组个数为1,2,22…2k=n,每次循环的时间复杂度乘以子数组隔宿即可,也就是
    T ( n ) = 1 ( n − 1 ) + 2 ( n 2 − 1 ) + 2 2 ( n 2 2 − 1 ) + . . . + 2 k ( n 2 k − 1 ) = n − 1 + n − 2 + n − 2 2 + . . . n − 2 k ∵ n = 2 k ∴ k = l o g 2 n ∴ T ( n ) = l o g 2 n − 2 n + 1 \begin{aligned} T(n)&=1(n-1)+2(\frac{n}{2}-1)+2^2(\frac{n}{2^2}-1)+...+2^k(\frac{n}{2^k}-1)\\ &=n-1+n-2+n-2^2+...n-2^k\\ &\because n=2^k\\ &\therefore k=log_2^n\\ &\therefore T(n)=log_2^n-2n+1 \end{aligned} T(n)=1(n1)+2(2n1)+22(22n1)+...+2k(2kn1)=n1+n2+n22+...n2kn=2kk=log2nT(n)=log2n2n+1
2.最坏时间复杂度
  • 就是快排每次划分将数组划分成的两个子数组长度为I1=0I2=n-1

    设 n 为待排序数组中的元素个数, T(n) 为算法需要的时间复杂度,递归得:
    T ( n ) = { D ( 1 ) , n ≤ 1 D ( n ) + T ( 0 ) + T ( n − 1 ) , n > 1 T(n)= \begin{cases} D(1),&n\leq1\\ D(n)+T(0)+T(n-1),&n>1 \end{cases} T(n)={D(1),D(n)+T(0)+T(n1),n1n>1
    所以
    T ( n ) = D ( n ) + T ( n − 1 ) = D ( n ) + D ( n − 1 ) + T ( n − 2 ) = ( n − 1 ) + ( n − 2 ) + ( n − 3 ) + . . . . + ( n − ( n − 1 ) ) = ( n − 1 ) + ( n − 2 ) + . . . + 0 = n ( n − 1 ) 2 = O ( n 2 ) \begin{aligned} T(n)&=D(n)+T(n-1)\\ &=D(n)+D(n-1)+T(n-2)\\ &=(n-1)+(n-2)+(n-3)+....+(n-(n-1))\\ &=(n-1)+(n-2)+...+0\\ &=\frac{n(n-1)}{2}\\ &=O(n^2) \end{aligned} T(n)=D(n)+T(n1)=D(n)+D(n1)+T(n2)=(n1)+(n2)+(n3)+....+(n(n1))=(n1)+(n2)+...+0=2n(n1)=O(n2)

  • 第二中理解:最坏时间复杂度其实就是已经排好了的数组,再次快排,子数组长度为(n-1),(n-2),…,0,时间复杂度就是本身遍历的长度,相加即为快排时间复杂度:
    T ( n ) = ( n − 1 ) + ( n − 2 ) + ( n − 3 ) + . . . . + ( n − ( n − 1 ) ) = ( n − 1 ) + ( n − 2 ) + . . . + 0 = n ( n − 1 ) 2 = O ( n 2 ) \begin{aligned} T(n)&=(n-1)+(n-2)+(n-3)+....+(n-(n-1))\\ &=(n-1)+(n-2)+...+0\\ &=\frac{n(n-1)}{2}\\ &=O(n^2) \end{aligned} T(n)=(n1)+(n2)+(n3)+....+(n(n1))=(n1)+(n2)+...+0=2n(n1)=O(n2)

3.平均时间复杂度
  • 就是每次划分将数组划分成的两个子数组的长度不确定,都是等可能,求时间复杂度就是算个平均值如下:

    { I 1 = 0 , I 2 = n − 1 I 1 = 1 , I 2 = n − 2 . . . . I 1 = n − 1 , I 2 = 0 \begin{cases} &I1=0,I2=n-1\\ &I1=1,I2=n-2\\ &....\\ &I1=n-1,I2=0\\ \end{cases} I1=0I2=n1I1=1I2=n2....I1=n1I2=0

    所以求解如下,思路就是求平均:
    T ( n ) = D ( n ) + 1 n ∑ i = 0 n − 1 [ T ( i ) + T ( n − 1 − i ) ] = D ( n ) + 2 n ∑ i = 0 n − 1 T ( i ) . . . ( 1 ) 式 ∴ T ( n − 1 ) = D ( n − 1 ) + 2 n ∑ i = 0 n − 2 T ( i ) . . . ( 2 ) 式 ∴ n ∗ ( 1 ) − ( n − 1 ) ∗ ( 2 ) 得 : n T ( n ) − ( n − 1 ) T ( n − 1 ) = n D ( n ) + 2 ∑ i = 0 n − 1 T ( i ) − ( n − 1 ) D ( n − 1 ) − 2 ∑ i = 0 n − 2 T ( i ) 整理得 : T ( n ) n + 1 = T ( n − 1 ) n + 2 ( n − 1 ) n ( n − 1 ) 令 B n = T ( n ) n + 1 ,得 \begin{aligned} T(n)&=D(n)+\frac{1}{n}\sum_{i=0}^{n-1}{[T(i)+T(n-1-i)]}\\ &=D(n)+\frac{2}{n}\sum_{i=0}^{n-1}{T(i)}...(1)式\\ &\therefore T(n-1)=D(n-1)+\frac{2}{n}\sum_{i=0}^{n-2}{T(i)}...(2)式\\ &\therefore n*(1)-(n-1)*(2)得:\\ &nT(n)-(n-1)T(n-1)=nD(n)+2\sum_{i=0}^{n-1}{T(i)}-(n-1)D(n-1)-2\sum_{i=0}^{n-2}{T(i)}\\ &整理得:\frac{T(n)}{n+1}=\frac{T(n-1)}{n}+\frac{2(n-1)}{n(n-1)}\\ &令B_n=\frac{T(n)}{n+1},得\\ \end{aligned} T(n)=D(n)+n1i=0n1[T(i)+T(n1i)]=D(n)+n2i=0n1T(i)...(1)T(n1)=D(n1)+n2i=0n2T(i)...(2)n(1)(n1)(2):nT(n)(n1)T(n1)=nD(n)+2i=0n1T(i)(n1)D(n1)2i=0n2T(i)整理得:n+1T(n)=nT(n1)+n(n1)2(n1)Bn=n+1T(n),得
    image-20220813232045131

    然后求B(n)反代求出T(n),求解过程很复杂不在此描述,最终时间复杂度为
    O ( n l o g   2 n ) O(nlog~2^n) O(nlog 2n)

综上:快速排序最好时间复杂度为 O(nlog2n) ,最坏时间复杂度为 O(n2) ,平均时间复杂度为 O(nlog2n)

快速排序的一些改进方案

  1. 将快速排序的递归执行改为非递归执行

  2. 当问题规模 n 较小时 (n≤16) ,采用直接插入排序求解

  3. 每次选取 prior 前将数组打乱

  4. 每次选取
    E [ f i r s t ] + E [ L a s t ] 2 \frac{E[first]+E[Last]}{2} 2E[first]+E[Last]

    E [ f i r s t ] + E [ l a s t ] + E [ ( f i r s t + l a s t ) / 2 ] 3 \frac{E[first]+E[last]+E[(first+last)/2]}{3} 3E[first]+E[last]+E[(first+last)/2]
    作为 prior

快排的Java实现:

/**
 * 快速排序
 * 通过一趟排序将待排序记录分割成独立的两部分,其中一部分记录的关键字均比另一部分关键字小,
 * 则分别对这两部分继续进行排序,直到整个序列有序。
 * @author Answer
 * 2022.8.11
 */
public class QuickSort 
{	
    //交换数据函数包装
	private static void swap(int[] data, int i, int j) 
    {
		int temp = data[i];
		data[i] = data[j];
		data[j] = temp;
	}

    //函数主体
	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);//low < end,是用于迭代时防止超出范围的限制
				while (high > start && data[--high] - base >= 0);
				if (low < high) 
                {
					swap(data, low, high);
				} 
                else 
                {
					break;
				}
			}
			swap(data, start, high);
			
			subSort(data, start, high - 1);//递归调用
			subSort(data, high + 1, end);
		}
	}
	public static void quickSort(int[] data)
    {
		subSort(data,0,data.length-1);
	}
	
	public static void main(String[] args) 
    {
		int[] data = { 9, -16, 30, 23, -30, -49, 25, 21, 30 };
		System.out.println("排序之前:\n" + java.util.Arrays.toString(data));
		quickSort(data);
		System.out.println("排序之后:\n" + java.util.Arrays.toString(data));
	}
}

  • 快排分内外层两循环,其中两个内层循环做的是将将当前小于pivot的元素分到一边(结束时是以大于pivot的元素head结束),将当前大于pivot的元素分到另一边(结束时是以小于pivot的元素tail结束),

    然后交换head和tail,再次进入外层循环。通过两层循环将大于和小于pivot的元素进行分组,再对子数据进行iteration。

  • high=end+1;这个设定很微妙!大大简化代码量!函数体中要排序的下标范围是1~array.length-1,但设置的头是0,尾部是array.length这样的设定决定函数在对pivot进行比对的时候,需要先自增自减再比对,当然也可以设定头是1,尾部是array.length-1。这样就需要先比较,再根据判断结果决定是否需要对下标进行移动,因此再内层循环中需添加if语句,代码冗杂。不如第一种精巧的设定

  • 迭代注意:再函数题内部用于迭代函数的参数一般不写具体数值,否则无论迭代多少次,参数均不变,与迭代的目的向背。而应该写的是函数内部定义的变量,这样函数执行一次参数都发生变化,才符合我们的预期。

5. Arrays工具类得使用

java.util.Arrays类即为操作数组的工具类,包含了用来操作数组(比如排序和搜索)的各种方法,可以直接调用Arrays类中的方法对数组进行操作

1boolean equals(int[] a,int[] b)判断两个数组是否相等。
2String toString(int[] a)输出数组信息。
3void fill(int[] a,int val)将指定值填充到数组之中
4void sort(int[] a)对数组进行排序。
5int binarySearch(int[] a,int key)对排序后的数组进行二分法检索指定的值。

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

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

相关文章

【PCL】PCL点云库介绍及VS环境配置

文章目录PCL介绍Windows PCL环境配置PCL介绍 PCL是跨平台点云处理库&#xff0c;用来点云可视化、分割、聚类等应用。 PCL官网在这&#xff1a;https://pointclouds.org/ Github库在这&#xff08;这里用1.8.1&#xff09;&#xff1a;https://github.com/PointCloudLibrary…

DASCTF X GFCTF 2022十月挑战赛 - pwn

DASCTF X GFCTF 2022十月挑战赛 - pwn 简单题&#xff0c;自己做了一下发现要比官方wp思路麻烦一点&#xff0c;所以这里就用官方wp的思路 高版本编译出来的&#xff0c;所以没有csu这种万能的gadget&#xff0c;果断看一下汇编 看完之后仔细思考了一下发现这里完全可以使用…

案例篇:Python爬虫的多重领域使用

大家好呀&#xff01; 相信大家早有体会&#xff0c;大数据时代已到&#xff0c;数据的获取和分析已被应用于各行各业&#xff0c;在诸多领域承担着重要决策的作用&#xff0c;如互联网就业选择。 Python爬虫作为最好的数据采集技术&#xff0c;市场对它需求一直在增涨&#xf…

vue3-tauri-chat:基于tauri聊天实例|tauri仿微信客户端

Vue3.jsTauri桌面端聊天实例|tauri仿微信/QQ聊天TauriChat。 基于taurivite3.xvue3element-plus等技术开发客户端仿微信/QQ聊天实战案例。实现发送消息、预览图片/视频/网址链接、拖拽/粘贴发送图片、朋友圈等功能。 使用技术 编辑器&#xff1a;VScode使用技术&#xff1a;ta…

【C++笔试强训】第十五天

&#x1f387;C笔试强训 博客主页&#xff1a;一起去看日落吗分享博主的C刷题日常&#xff0c;大家一起学习博主的能力有限&#xff0c;出现错误希望大家不吝赐教分享给大家一句我很喜欢的话&#xff1a;夜色难免微凉&#xff0c;前方必有曙光 &#x1f31e;。 &#x1f4a6;&a…

C++模板

目录 ​一、认识模板 1.什么是模板 2.模板的分类 二、函数模板 1.泛型和函数模板 2.函数模板的格式 三、类模板 四、实例化 1.隐式实例化 2.显式实例化 3.隐式类型转换 4.模板参数的匹配原则 一、认识模板 1.什么是模板 模板&#xff08;Template&#xff09;指C…

Java笔记(十一)

文献种类&#xff1a;专题技术总结文献 开发工具与关键技术&#xff1a; IntelliJ IDEA、Java 语言 作者&#xff1a; 方建恒 年级&#xff1a; 2020 撰写时间&#xff1a; 2022 年 10 月 28 日 Java笔记(十一) 今天我给大家继续分享一下我的Java笔记&#xff0c; 我们来了解…

CTFHub | 报错注入

0x00 前言 CTFHub 专注网络安全、信息安全、白帽子技术的在线学习&#xff0c;实训平台。提供优质的赛事及学习服务&#xff0c;拥有完善的题目环境及配套 writeup &#xff0c;降低 CTF 学习入门门槛&#xff0c;快速帮助选手成长&#xff0c;跟随主流比赛潮流。 0x01 题目描述…

第二站:分支与循环(第二幕)

目录 三、循环 1.while循环 &#xff08;1&#xff09;基本原理与用法 &#xff08;2&#xff09;break在while循环中的作用 &#xff08;3&#xff09;continue在while循环中的作用 &#xff08;4&#xff09;一图总结while循环 2.for循环 &#xff08;1&#xff09;基…

[SpringBoot] 多模块统一返回格式带分页信息

✨✨个人主页:沫洺的主页 &#x1f4da;&#x1f4da;系列专栏: &#x1f4d6; JavaWeb专栏&#x1f4d6; JavaSE专栏 &#x1f4d6; Java基础专栏&#x1f4d6;vue3专栏 &#x1f4d6;MyBatis专栏&#x1f4d6;Spring专栏&#x1f4d6;SpringMVC专栏&#x1f4d6;SpringBoot专…

算法刷题路线总结与相关资料分享

算法刷题路线总结与相关资料分享前言一、算法刷题路线总结二、算法题刷题步骤三、基础数据结构与算法知识1、时间复杂度2、空间复杂度3、线性表4、栈与队列5、树四、算法学习相关资料推荐1.数据结构与算法基础2.专项刷题路线资料3.算法课程视频资料后记前言 本文为算法刷题路线…

双十一数码产品哪些值得买?双十一好物产品分享

双十一必然是数码产品最值得买的&#xff0c;因为这类产品的优惠力度往往是最大的&#xff0c;所以每年的双十一都是升级数码设备的好时机&#xff0c;今天为大家带来的是便是个人推荐的双十一数码好物。好了&#xff0c;废话不再多说&#xff0c;我们开车吧。 一、不伤耳的骨…

postman 实用教程(含带 token 访问需登录权限的接口)

下载安装 Postman 访问官网下载安装 Postman https://www.postman.com/downloads/?utm_sourcepostman-home 新建文档 右键菜单可以重命名 新建接口 选择接口类型输入接口若传入参数格式为 json &#xff0c;则选择 Body 中的 raw 和 JSON输入传入的参数&#xff08;json格式&a…

计算机网络--数据链路层

今天来讲网络协议栈的最后一层&#xff0c;数据链路层(物理层我们不考虑了)&#xff0c;我们之前学到&#xff0c;TCP协议提供了数据传输的可靠性&#xff0c;IP层决定数据报从哪到哪&#xff0c;那么数据报是如何从一个结点到下一个结点呢&#xff1f;得到相应如何返回呢&…

(02)Cartographer源码无死角解析-(09) gflags与glog简介、及其main函数讲解

本人讲解关于slam一系列文章汇总链接:史上最全slam从零开始&#xff0c;针对于本栏目讲解(02)Cartographer源码无死角解析-接如下: (02)Cartographer源码无死角解析- (00)目录_最新无死角讲解&#xff1a;https://blog.csdn.net/weixin_43013761/article/details/127350885 文…

软件工程结构化设计

目录 结构化分析与结构化设计的关系&#xff1a; 体系结构设计概念&#xff1a; 图形工具&#xff1a; 层次图&#xff1a;调用关系​编辑 HIPO图&#xff1a;层次图IPO图 软件结构图&#xff1a; 软件设计原则&#xff1a; 模块化&#xff1a; 模块划分注意事项&#xf…

巴什博弈——范围拿物品问题

巴什博弈 巴什博弈&#xff08;Bash game&#xff09; 是一个双人博弈&#xff1a;有一堆总数为n的物品&#xff0c;2名玩家轮流从中拿取物品。每次至少拿1件&#xff0c;至多拿m件&#xff0c;不能不拿&#xff0c;最终将物品拿完者获胜。 巴什博弈除了两人轮流按一定数量拿物…

【黄啊码】MySQL入门—14、细说数据库的MVCC机制

大家好&#xff0c;我是黄啊码。上一篇文章中&#xff0c;我们讲到了锁的划分&#xff0c;以及乐观锁和悲观锁的思想。今天我们就来看下 MVCC&#xff0c;它就是采用乐观锁思想的一种方式。那么它到底有什么用呢&#xff1f; 我们知道事务有 4 个隔离级别&#xff0c;以及可能…

共谋韬略、共巢未来,电巢与韬略“战略合作签约仪式”圆满举办!

前言 2022年10月27日下午&#xff0c;电巢科技与韬略科技齐聚深圳南山&#xff0c;共同举办了隆重的战略合作签约仪式&#xff0c;双方就整合核心资源、共同打造高质量数字化内容等战略方针达成了一致&#xff0c;携手开启合作新篇章。 电巢科技和韬略科技基于相契合的发展战略…

Numpy基础教程

1 Numpy 对象2 Numpy创建numpy.array 构造器来创建numpy.emptynumpy.zerosnumpy.onesnumpy.arangeNumpy索引3 Numpy常用操作numpy.reshapenumpy.reshape(arr,newshape,order C)numpy.transposenumpy.expand_dimsnumpy.squeezeNumpy功能十分强大的python扩展库&#xff0c;数学…