当前位置: 首页 > news >正文

一起学数据结构(2)——线性表及线性表顺序实现

目录

1. 什么是数据结构:

 1.1 数据结构的研究内容:

1.2 数据结构的基本概念:

1.2.1 逻辑结构:

 1.2.2 存储结构:

2. 线性表:

2.1 线性表的基本定义:

2.2 线性表的运用:

3 .线性表的顺序表示及实现(顺序表):

   3.1 顺序表的概念及结构:

 3.2 顺序表的代码实现:

3.2.1 顺序表的创建、初始化及销毁:

3.3 顺序表的四个特殊操作(头插、头删、尾插、尾删):

3.3.1 尾插:

3.3.2 尾删:

3.3.3 头插: 

3.3.4 头删:

 3.4 对顺序表的随机位置进行增删操作:

3.4.1 对顺序表的随机位置进行添加数据的操作:

3.4.2 对顺序表的随机位置进行删除数据的操作:

4. 代码总览:

4.1 头文件Seqlist.h:

4.2 函数功能实现文件 Seqlist.c

4.3 测试函数功能文件 test.c:


 上一篇文章中,对数据结构中用于评判算法的两个标准,即:时间复杂度、空间复杂度进行简单的介绍及解释。本篇文章,会对:什么是数据结构?数据结构的基本概念进行简单的介绍。着重介绍线性表和线性表的顺序实现。

1. 什么是数据结构:

 1.1 数据结构的研究内容:

   计算机主要是被用于进行数值计算,这个过程可以分为以下几步:

1.从具体问题中抽象出数学模型。

2.设计相应的算法

3.对程序进行测试,调试等。

对于第一个步骤,也可以分为:分析问题、提取操作对象、找出操作对象之间的关系、用数学语言进行表述这四步。对于提取操作对象和找出操作对象之间的关系这两步,就是数据结构研究的主要内容

1.2 数据结构的基本概念:

首先给出数据结构的定义:

数据结构是相互之间一种或多种特定关系的数据元素的集合。或者说:数据结构是带“结构”的数据元素的集合,"结构“就是指数据元素之间存在的关系。对于数据结构,包含了逻辑结构和存储结构两个层次。

(注:本文只是对数据类型进行简单的介绍,所以,对于下面逻辑结构和存储结构,只给出概念与分类,其中包含的具体内容将会在后续的文章中进行介绍)

1.2.1 逻辑结构:

数据的逻辑结构是指从逻辑关系上描述数据 ,它与数据的存储无关,是独立于计算机的。数据结构的类型如下图所示:

 1.2.2 存储结构:

数据对象在计算机中的存储表示称为数据的存储结构,也成为物理结构。数据元素在计算机中有两种基本的存储结构,分别是顺序存储结构和链式存储结构:

 

2. 线性表:

2.1 线性表的基本定义:

对于线性表,一个很典型的例子就是26英文字母的字母表:

                                                        (A,B,C,D......,Z)

从字母表中可以看出看出线性表的一些性质,例如:虽然线性表中的数据并不相同,但是同一线性表中的元素必定具有相同的特性,即属于同一数据对象。线性表在逻辑上是线性结构,也就说是连续的一条直线。但是在物理结构上并不一定是连续的,线性表在物理上存储时,通常以数组和链式结构的形式存储。

2.2 线性表的运用:

对于线性表的运用,文章给出两个例子:

例1:一元多项式的运算:

  在数学中,一个一元多项通常可以写成下面的形式:

                                         P_n(x) = P_0+P_1x+P_2x^2+......+P_nx^n

在对一元多项式进行运算之前,首先要知道如何在计算机表示一元多项式。表示一元多项式,便是线性表的一个应用。

通过观察一元多项式可以发现:一元多项式的系数下标,与x的指数相同。因此,可以用线性表来存储一元多项式中各项系数,即:

                                        P = (P_0,P_1,P_2,......P_n)

这时,对于一元多项式中各项中,x的指数便隐藏在各项的系数下标中。

此时,假设还有一个一元多项式Q_m(x),运算Q_m(x)P_n(x)这两个一元多项式的和,便可以通过上面的思想,用线性表来表示各项系数之和,即:

                                      A = (P_0+Q_0,P_1+Q_1,......,P_n+Q_m)

例子2:稀疏多项式的表示:

给定一个稀疏多项式:

                                      S(x) = 1+3x^{10000}+2x^{20000}

对于稀疏多项式,如果再采用上面存储多项式中各项系数的方法,则需要开辟20001个空间,但是上面的多项式,一共只有3个非零元素,所以,采用上面介绍的存储方法,会造成存储空间的极大浪费。

对于稀疏多项式的存储方法,应该存储每一项的系数和指数。如果把稀疏多项式改写成一元多项式的形式,即:

                                      P_n(x) = p_1x^{e_1}+p_2x^{e_2}+......+p_nx^{e_n}

运用线性表对每一项的系数和指数保存,即:

                                       P_n(x) = ((p_1,e_1),(p_2,e_2),......(p_n,e_n))

由于本文主要是通过例子来介绍线性表,所以对于稀疏多项式的运算,文章不展开介绍,只给出运算方法及大体的运算规则:

假设由两个稀疏多项式P_n(x)Q_m(x)。对两式进行相加时,需要先创建一个新的数组,假设为C,在运算时,遵从以下规则:

分别从头遍历并且比较两个稀疏多项式,对于e相同的项,则两项系数相加,若系数之和不为0,则在数组C中记录相加项的系数(P_i+Q_i),对于e不同的项,则先将e较小的项添加到C中。

3 .线性表的顺序表示及实现(顺序表):

   3.1 顺序表的概念及结构:

     顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储。这种表示也称作线性表的顺序存储结构或顺序映像。特点是:逻辑上相邻的元素,其物理此些许也是相邻的,并且在顺序表中,任一元素都可以随机存取。即:

 3.2 顺序表的代码实现:

3.2.1 顺序表的创建、初始化及销毁:

顺序表可以分为两种,分别是:静态顺序表、动态顺序表,对于静态顺序表,其代码表示为:

#define N 100
typedef int SLDataType;
struct Seqlist
{SLDataType arr[N];  //定长数组int size;           //有效数据个数
}Seqlist; 

对于静态顺序表,有一个极大的缺陷,便是内存大小使用不够灵活。比如上面给出的代码,如果需要存储的数据的个数只有几个,则会造成极大的内存空间浪费,如果需要存储的数据的个数大于100,则超出了数组的最大存储范围。所以,为了解决上述问题,在创建顺序表时,一般创建对于内存使用更加灵活的动态顺序表,代码如下:

typedef int SLDataType;typedef struct Seqlist
{SLDataType* a;    //动态开辟数组的方式,a表示数组首元素地址size_t size;      //数组中有效的数据个数size_t capacity;  //容量大小
}SL;

使用动态顺序表后,对于内存空间的使用便灵活很多,例如,编写一个内存空间检查函数,每次向顺序表中添加数据元素时,先通过内存空间检查函数进行检查,当内存空间不够用时,可以通过动态内存管理函数realloc对已有的内存空间进行增容。

对于顺序表的初始化,将顺序表初始化函数命名为SLInit,函数内容如下:

void SLInit(SL* ps)
{ps->a = NULL;ps->size = 0;ps->capacity = 0;
}

上面的代码只是给了初始化函数的大体框架,在实际使用中,并不会把顺序表中的三项内容全都初始化为0,而是在初始化时,开辟一定的空间。例如在初始化时,给予4字节大小的空间:

void SLInit(SL* ps)
{ps->a =(SLDataType*)malloc(sizeof(SLDataType)*4);if (ps->a == NULL){perror("malloc");exit (-1);}ps->size = 0;ps->capacity = 4;
}

其中的malloc是动态内存管理函数的一种,对于动态内存管理函数的使用,可以参考下面给出的文章链接中的内容C语言——动态内存管理:_爱写代码的粉毛护理的博客-CSDN博客

if语句用于判断是否成功的开辟了空间。

对于动态顺序表的销毁,直接使用free函数对动态开辟的空间进行释放即可。代码如下:

void SLDestroy(SL* ps)
{free(ps);ps->a = NULL;ps->size = ps->capacity = 0;
}

3.3 顺序表的四个特殊操作(头插、头删、尾插、尾删):

3.3.1 尾插:

给出一个顺序表,其中的数组中存储的元素如图所示:

 由上面对于顺序表的定义可知:

capacity表示顺序表的数组的容量大小

a表示数组,后面的数字表示这个数组中存储的元素

size表示数组中存储元素的个数

size-1用来表示数组下标

对上述数组进行尾插操作,假设第一次插入数字15,则:

 进行尾插后,令用来表示数组中存储元素个数的变量size+1

此时,再进行一次尾插,插入数字15,则:

进行尾插后,同样令用来表示数组中存储元素格式的变量size+1; 此时,size = 7 = capacity

。表示顺序表中的数组的空间已经被占满,如果还需要进行尾插操作,则需要对数组的空间进行扩容。因为,为了避免上面的情况发生,应该在每次进行尾插操作之前,都对顺序表进行一次检查,如果size = capacity,则对数组的空间进行扩容,对于扩容空间的大小,一般扩为原来空间的2倍,代码如下:

void SLPushBack(SL* ps, SLDataType x)
{if (ps->size == ps->capacity){SLDataType* tmp = (SLDataType*)realloc(ps->a, ps->capacity * 2 * (sizeof(SLDataType)));if(tmp == NULL){perror("realloc");}ps->a = tmp;ps->capacity = ps->capacity * 2;}ps->a[ps->size] = x;ps->size++;
}

 对于上面给出的尾插代码,最核心的部分就是对内存空间进行扩容,即:

 SLDataType* tmp = (SLDataType*)realloc(ps->a, ps->capacity * 2 * (sizeof(SLDataType)));

对于理解用于扩容的代码,需要将内存空间和capacity的概念分清,capacity只是代表了已经开辟的内存空间的个数,不会反应内存空间的大小,因此,在上面用于扩容的代码中,ps->capacity * 2只是表示将内存空间的数量扩大到2倍,想到达到对内存空间的大小扩容到2倍,需要再乘上存储的数据的类型,即(sizeof(SLDataType)

注:对于用于扩容的函数realloc,也可以在下面给出的文章中进行了解C语言——动态内存管理:_爱写代码的粉毛护理的博客-CSDN博客)

如果已经掌握了对动态内存管理函数的初步使用,会发现,尾插的代码中,再对内存空间进行扩容后,并没有用free函数去释放内存空间。这是因为realloc函数的返回值的特殊性质。这个性质同样也可以在上面给出的文章链接中进行了解,在本文中会进行简要的解释:

上面提到的realloc函数的返回值的特殊性质,即:原地扩容、异地扩容。

对于原地扩容,如果对内存进行扩容时,后面有足够多的内存空间可以达到对已有内存空间进行扩容的目的,则realloc函数返回值返回已有空间的首地址。

对于异地扩容,如果对内存进行扩容时,后面没有足够多的内存空间可以达到对已有内存空间进行扩容的目的,则realloc函数会寻找一个新的空间,这个空间的地址是随机的,并且返回值返回这个新空间的首地址。这两个性质,可以由下面的代码进行演示:

int main()
{int* p1 = (int*)malloc(12);int* p2 = (int*)realloc(p1, 2);printf("%p  %p\n",p1, p2);int* p3 = (int*)malloc(10);int* p4 = (int*)realloc(p3, 200);printf("%p  %p",p3, p4);return 0;
}

结果如下:

可以验证,p2的地址表示,此时是原地扩。

此时,p3,p4地址不同,是异地扩。 

所以,realloc函数对于扩容时不同情况的处理很灵活,不需要在扩容后用free函数释放内存空间。为了测试尾插的功能是否正常,封装一个函数,插入1,2,3,4,5,6这几个数字:

void test1()
{SL s1;SLInit(&s1);SLPushBack(&s1, 1);SLPushBack(&s1, 2);SLPushBack(&s1, 3);SLPushBack(&s1, 4);SLPushBack(&s1, 5);SLPushBack(&s1, 6);SLPrint(&s1);
}

结果如下:

 

3.3.2 尾删:

尾删就是从末尾向前删除元素,原理比较简单,只需要让size--即可

//尾删:
void SLPopBack(SL* ps)
{ps->size--;
}

利用下面的代码测试尾删的功能:

void test1()
{SL s1;SLInit(&s1);SLPushBack(&s1, 1);SLPushBack(&s1, 2);SLPushBack(&s1, 3);SLPushBack(&s1, 4);SLPushBack(&s1, 5);SLPushBack(&s1, 6);SLPopBack(&s1); SLPopBack(&s1);SLPrint(&s1);
}

结果如下:

3.3.3 头插: 

在执行尾插操作时说到,每次插入前,需要检查以下数组的内存空间是否足够。在头插中,同样需要对内存空间进行检查,所以,为了方便操作,不如将尾插中用于检查数组内存空间的代码封装成一个函数。

void SLCheckCapacity(SL* ps)
{if (ps->size == ps->capacity){SLDataType* tmp = (SLDataType*)realloc(ps->a, ps->capacity * 2 * (sizeof(SLDataType)));if (tmp == NULL){perror("realloc");}ps->a = tmp;ps->capacity = ps->capacity * 2;}
}

对于头插,只需要将已有的元素全部向后移动一位,再把想要插入的元素插入到数组的首个位置。此时,因为插入了一个元素,所以,顺序表中的size+1例如,头插一个数字6,可以用图表示为:

原数组:

 全部元素向后挪动一位:

头插数字6 :

 

 将上述过程用代码表示:

void SLPushFront(SL* ps, SLDataType x)
{SLCheckCapacity(ps);int end = ps->size - 1;while (end >= 0){ps->a[end+1] = ps->a[end];end--;}ps->a[0] = x;ps->size++;
}

用下列函数对头插功能进行设置:

void test2()
{SL s2;SLInit(&s2);SLPushBack(&s2, 1);SLPushBack(&s2, 2);SLPushBack(&s2, 3);SLPushBack(&s2, 4);SLPushBack(&s2, 5);SLPushFront(&s2, 6);SLPrint(&s2);
}

结果如下:

(注:第一行的1,2,3,4是测试尾插的结果,头插的结果是第一行) 

3.3.4 头删:

头删的过程与头插相反,进行头插的操作时,需要把元素整体向后移动,且移动的顺序是从后向前,对于头删,则是需要从前向后一次覆盖前面的数据。

void SLPopFront(SL* ps)
{if (ps->size == 0){return;}int start = 0;int end = ps->size - 1;while (start <= end){ps->a[start] = ps->a[start+1];start++;}ps->size--;
}

用下面的函数测试头删的功能:

void test3()
{SL s3;SLInit(&s3);SLPushBack(&s3, 1);SLPushBack(&s3, 2);SLPushBack(&s3, 3);SLPushBack(&s3, 4);SLPushBack(&s3, 5);SLPopFront(&s3);printf("头删:");SLPrint(&s3);
}

结果如下:

 3.4 对顺序表的随机位置i进行增删操作:

3.4.1 对顺序表的随机位置i进行添加数据的操作:

对随机位置i添加数据的操作,与头插的操作流程相似。基本可以分为以下几步:

1.判断i这个位置对于数组下标而言是否合法,即0<=i<=size-1

2.将位置i以及后面的元素整体后移动一位。

3.将新的元素插入到数组中下标为i-1的位置

4.将size+1

用图来表示上述过程,及:

 将位置i以及后续元素向后移动一位:

 最后,向位置为i的地方插入元素即可。因为多插入了一个元素,最后需要size+1

代码如下:

void SLInsert(SL* ps, size_t i, SLDataType x)
{if (i < 0 || i >(ps->size - 1)){printf("坐标非法");exit(-1);}size_t end = ps->size - 1;for (size_t end = ps->size - 1; end > i-1; end--){ps->a[end + 1] = ps->a[end];}ps->a[i - 1] = x;ps->size++;
}

用下面的代码验证随机位置i插入功能是否正常:

void test4()
{SL s4;SLInit(&s4);SLPushBack(&s4, 1);SLPushBack(&s4, 2);SLPushBack(&s4, 3);SLPushBack(&s4, 4);SLPushBack(&s4, 5);SLInsert(&s4, 3, 6);SLPrint(&s4);}

结果如下:

(注:结果是最后一行数字所展示的效果) 

 

3.4.2 对顺序表的随机位置进行删除数据的操作:

对于在顺序表的随机位置i删除数据的操作可以分为以下几步:size-1

1.检查位置i对于数组下标是否合理,即1<=i<=size-1

2.将位置i后面的元素整体向前移动一位。

3. 因为删除了一个元素,所以size-1

将上述过程用图进行表示:

将位置i后面的元素整体向前移动一位:

 

最后 size-1

将上述过程用代码表示:

void SLErase(SL* ps, size_t i)
{if (i <= 0 || (i > ps->size - 1)){printf("坐标非法");}size_t start = i-1;while (start <= ps->size - 1){ps->a[start] = ps->a[start + 1];start++;}ps->size--;
}

用下面的函数测试功能:

void test5()
{SL s5;SLInit(&s5);SLPushBack(&s5, 1);SLPushBack(&s5, 2);SLPushBack(&s5, 3);SLPushBack(&s5, 4);SLPushBack(&s5, 5);SLErase(&s5, 3);SLPrint(&s5);}

结果如下:

 (注:最后一行的数字对应着测试的功能的结果)

4. 代码总览:

4.1 头文件Seqlist.h:

#include<stdio.h>
#include<assert.h>
#include<stdlib.h>//#define N 100
//typedef int SLDataType;
//struct Seqlist
//{
//	SLDataType arr[N];
//	int size;
//}Seqlist;typedef int SLDataType;
typedef struct Seqlist
{SLDataType* a;size_t size;size_t capacity;
}SL;//用于打印测试:
void SLPrint(SL* ps);
//用于初始化顺序表
void SLInit(SL* ps);//用于销毁顺序表:
void SLDestroy(SL* ps);//尾插:
void SLPushBack(SL* ps, SLDataType x);//尾删
void SLPopBack(SL* ps);//检测内存空间
void SLCheckCapacity(SL* ps);//头插
void SLPushFront(SL* ps, SLDataType x);//头删
void SLPopFront(SL* ps);//随机位置插入
void SLInsert(SL* ps,size_t i ,SLDataType x);//随机位置删除
void SLErase(SL* ps, size_t i);

4.2 函数功能实现文件 Seqlist.c

#include"Seqlist.h"//初始化顺序表
void SLInit(SL* ps)
{ps->a =(SLDataType*)malloc(sizeof(SLDataType)*4);if (ps->a == NULL){perror("malloc");exit (-1);}ps->size = 0;ps->capacity = 4;
}//销毁顺序表void SLDestroy(SL* ps)
{free(ps->a);ps->a = NULL;ps->size = ps->capacity = 0;
}//尾插:
void SLPushBack(SL* ps, SLDataType x)
{SLCheckCapacity(ps);ps->a[ps->size] = x;ps->size++;
}//用于打印数据
void SLPrint(SL* ps)
{int i = 0;for (i = 0; i < ps->size; i++){printf("%d ", ps->a[i]);}printf("\n");
}//尾删:
void SLPopBack(SL* ps)
{ps->size--;
}//检查内存空间:
void SLCheckCapacity(SL* ps)
{if (ps->size == ps->capacity){SLDataType* tmp = (SLDataType*)realloc(ps->a, ps->capacity * 2 * (sizeof(SLDataType)));if (tmp == NULL){perror("realloc");}ps->a = tmp;ps->capacity = ps->capacity * 2;}
}//头插
void SLPushFront(SL* ps, SLDataType x)
{SLCheckCapacity(ps);int end = ps->size - 1;while (end >= 0){ps->a[end+1] = ps->a[end];end--;}ps->a[0] = x;ps->size++;
}//头删:
void SLPopFront(SL* ps)
{if (ps->size == 0){return;}int start = 0;int end = ps->size - 1;while (start <= end){ps->a[start] = ps->a[start+1];start++;}ps->size--;
}//随机位置插入:
void SLInsert(SL* ps, size_t i, SLDataType x)
{if (i < 0 || i >(ps->size - 1)){printf("坐标非法");exit(-1);}size_t end = ps->size - 1;for (size_t end = ps->size - 1; end > i-1; end--){ps->a[end + 1] = ps->a[end];}ps->a[i - 1] = x;ps->size++;
}//随机位置删除:
void SLErase(SL* ps, size_t i)
{if (i <= 0 || (i > ps->size - 1)){printf("坐标非法");}size_t start = i-1;while (start <= ps->size - 1){ps->a[start] = ps->a[start + 1];start++;}ps->size--;
}

4.3 测试函数功能文件 test.c:

#include"Seqlist.h"void test1()
{SL s1;SLInit(&s1);SLPushBack(&s1, 1);SLPushBack(&s1, 2);SLPushBack(&s1, 3);SLPushBack(&s1, 4);SLPushBack(&s1, 5);SLPushBack(&s1, 6);SLPopBack(&s1); SLPopBack(&s1);SLPrint(&s1);
}void test2()
{SL s2;SLInit(&s2);SLPushBack(&s2, 1);SLPushBack(&s2, 2);SLPushBack(&s2, 3);SLPushBack(&s2, 4);SLPushBack(&s2, 5);SLPushFront(&s2, 6);SLPrint(&s2);}void test3()
{SL s3;SLInit(&s3);SLPushBack(&s3, 1);SLPushBack(&s3, 2);SLPushBack(&s3, 3);SLPushBack(&s3, 4);SLPushBack(&s3, 5);SLPopFront(&s3);printf("头删:");SLPrint(&s3);
}void test4()
{SL s4;SLInit(&s4);SLPushBack(&s4, 1);SLPushBack(&s4, 2);SLPushBack(&s4, 3);SLPushBack(&s4, 4);SLPushBack(&s4, 5);SLInsert(&s4, 3, 6);SLPrint(&s4);}
void test5()
{SL s5;SLInit(&s5);SLPushBack(&s5, 1);SLPushBack(&s5, 2);SLPushBack(&s5, 3);SLPushBack(&s5, 4);SLPushBack(&s5, 5);SLErase(&s5, 3);SLPrint(&s5);}
int main()
{test1();test2();test3();test4();test5();return 0;
}

 

 

相关文章:

一起学数据结构(2)——线性表及线性表顺序实现

目录 1. 什么是数据结构&#xff1a; 1.1 数据结构的研究内容&#xff1a; 1.2 数据结构的基本概念&#xff1a; 1.2.1 逻辑结构&#xff1a; 1.2.2 存储结构&#xff1a; 2. 线性表&#xff1a; 2.1 线性表的基本定义&#xff1a; 2.2 线性表的运用&#xff1a; 3 .线性…...

mqtt协议流程图

转载于...

7、单元测试--测试RestFul 接口

单元测试–测试RestFul 接口 – 测试用例类使用SpringBootTest(webEnvironment WebEnvironment.RANDOM_PORT)修饰。 – 测试用例类会接收容器依赖注入TestRestTemplate这个实例变量。 – 测试方法可通过TestRestTemplate来调用RESTful接口的方法。 测试用例应该定义在和被测…...

国家留学基金委(CSC)|发布2024年创新型人才国际合作培养项目实施办法

2023年7月28日&#xff0c;国家留学基金委&#xff08;CSC&#xff09;发布了《2024年创新型人才国际合作培养项目实施办法》&#xff0c;在此知识人网小编做全文转载。详细信息请参见https://www.csc.edu.cn/chuguo/s/2648。 2024年创新型人才国际合作培养项目实施办法 第一章…...

找好听的配乐、BGM就上这6个网站,免费商用。

推荐几个音乐素材网站给你&#xff0c;各种类似、风格的都有&#xff0c;而且免费下载&#xff0c;还可以商用&#xff0c;建议收藏起来~ 菜鸟图库 https://www.sucai999.com/audio.html?vNTYxMjky 站内有上千首音效素材&#xff0c;网络流行的音效素材这里都能找到&#xf…...

【前端知识】React 基础巩固(三十五)——ReduxToolKit (RTK)

React 基础巩固(三十五)——ReduxToolKit (RTK) 一、RTK介绍 Redux Tool Kit &#xff08;RTK&#xff09;是官方推荐的编写Redux逻辑的方法&#xff0c;旨在成为编写Redux逻辑的标准方式&#xff0c;从而解决上面提到的问题。 RTK的核心API主要有如下几个&#xff1a; confi…...

android Android Studio Giraffe | 2022.3.1 版本Lombok不兼容 解决方案

android Android Studio Giraffe | 2022.3.1 版本Lombok不兼容 解决方案 1.查看当前的android studio 版本 Android Studio Giraffe | 2022.3.1 Build #AI-223.8836.35.2231.10406996, built on June 29, 2023 2.打开 idea 官网下载页面 idea下载历史版本 找到对应的版本编号…...

前端框架学习-基础前后端分离

前端知识栈 前端三要素&#xff1a;HTML、CSS、JS HTML 是前端的一个结构层&#xff0c;HTML相当于一个房子的框架&#xff0c;可类比于毛坯房只有一个结构。CSS 是前端的一个样式层&#xff0c;有了CSS的装饰&#xff0c;相当于房子有了装修。JS 是前端的一个行为层&#xff…...

数据中心电子电气设备常见的五种地线种类和做法

数据中心机房计算机系统的集成化程度很高&#xff0c;其正常工作对环境的要求很严格。接地&#xff0c;是指电力系统和电气装置的中性点、电气设备的外露导电部分和装置外导电部分经由导体与大地相连。其作用主要是防止人身遭受电击、设备和线路遭受损坏、预防火灾和防止雷击、…...

重学C++系列之STL库

一、什么是STL库 STL是“Standard Template Library”的缩写&#xff0c;中文翻译为“标准模板库”。CSTL是一套功能强大的C模板类&#xff0c;提供了通用的模板类和函数&#xff0c;这些模板类和函数可以实现多种流行和常用的算法和数据结构&#xff0c;如字符串操作、链表、队…...

JAVA SE -- 第十四天

&#xff08;全部来自“韩顺平教育”&#xff09; 泛型 一、泛型 1、基本介绍 ①泛型又称参数类型&#xff0c;是Jdk5.0出现的新特性&#xff0c;解决数据类型的安全性问题 ②在类声明或实例化时只要指定好需要的具体的类型即可 ③Java泛型可以保证如果程序在编译时没有发…...

微信小程序监测版本更新

在index.js里面 不放到app.js里面是因为有登录页面&#xff0c;在登录页面显示更新不太友好 onShow() {const updateManager wx.getUpdateManager()// 请求完新版本信息的回调updateManager.onCheckForUpdate(res > {if (res.hasUpdate) {// 新版本下载成功updateManage…...

《Java面向对象程序设计》学习笔记——第 2 章 基本数据类型、数组和枚举类型

专栏&#xff1a;《Java面向对象程序设计》学习笔记...

TDesign中后台管理系统-访问后端服务

目录 1 修改后端服务地址2 解决跨域问题3 动态获取菜单4 测试后端接口5 前后端联调总结 目前我们已经搭建了TDesign的前端和express的后端&#xff0c;目前是两个独立的应用。通常我们需要把前后端集成在一起&#xff0c;TDesign已经配置了相关的信息&#xff0c;只需要修改后端…...

【机器学习】Gradient Descent for Logistic Regression

Gradient Descent for Logistic Regression 1. 数据集&#xff08;多变量&#xff09;2. 逻辑梯度下降3. 梯度下降的实现及代码描述3.1 计算梯度3.2 梯度下降 4. 数据集&#xff08;单变量&#xff09;附录 导入所需的库 import copy, math import numpy as np %matplotlib wi…...

ElasticSearch基础篇-Java API操作

ElasticSearch基础-Java API操作 演示代码 创建连接 POM依赖 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:sch…...

解决uniapp的tabBar使用iconfont图标显示方块

今天要写个uniapp的移动端项目&#xff0c;底部tabBar需要添加图标&#xff0c;以往都是以图片的形式引入&#xff0c;但是考虑到不同甲方的主题色也不会相同&#xff0c;使用图片的话&#xff0c;后期变换主题色并不友好&#xff0c;所以和UI商量之后&#xff0c;决定使用icon…...

UE4/5C++多线程插件制作(0.简介)

目录 插件介绍 插件效果 插件使用 English 插件介绍 该插件制作&#xff0c;将从零开始&#xff0c;由一个空白插件一点点的制作&#xff0c;从写一个效果到封装&#xff0c;层层封装插件&#xff0c;简单粗暴的对插件进行了制作&#xff1a; 插件效果 更多的是在cpp中去…...

ChatFile实现相关流程

文本上传构建向量库后台库的内容 调用上传文件接口先上传文件 存在疑问:暂时是把文件保存在tmp文件夹,定时清理,是否使用云存储 根据不同的文件类型选取不同的文件加载器加载文件内容 switch (file.mimetype) {case application/pdf:loader new PDFLoader(file.path)breakc…...

15 文本编辑器vim

15.1 建立文件命令 如果file.txt就是修改这个文件&#xff0c;如果不存在就是新建一个文件。 vim file.txt 使用vim建完文件后&#xff0c;会自动进入文件中。 15.2 切换模式 底部要是显示插入&#xff0c;是编辑模式&#xff1b; 按esc&#xff0c;底部要是空白的&#xff0…...

椭圆曲线密码学(ECC)

一、ECC算法概述 椭圆曲线密码学&#xff08;Elliptic Curve Cryptography&#xff09;是基于椭圆曲线数学理论的公钥密码系统&#xff0c;由Neal Koblitz和Victor Miller在1985年独立提出。相比RSA&#xff0c;ECC在相同安全强度下密钥更短&#xff08;256位ECC ≈ 3072位RSA…...

SciencePlots——绘制论文中的图片

文章目录 安装一、风格二、1 资源 安装 # 安装最新版 pip install githttps://github.com/garrettj403/SciencePlots.git# 安装稳定版 pip install SciencePlots一、风格 简单好用的深度学习论文绘图专用工具包–Science Plot 二、 1 资源 论文绘图神器来了&#xff1a;一行…...

Day131 | 灵神 | 回溯算法 | 子集型 子集

Day131 | 灵神 | 回溯算法 | 子集型 子集 78.子集 78. 子集 - 力扣&#xff08;LeetCode&#xff09; 思路&#xff1a; 笔者写过很多次这道题了&#xff0c;不想写题解了&#xff0c;大家看灵神讲解吧 回溯算法套路①子集型回溯【基础算法精讲 14】_哔哩哔哩_bilibili 完…...

鱼香ros docker配置镜像报错:https://registry-1.docker.io/v2/

使用鱼香ros一件安装docker时的https://registry-1.docker.io/v2/问题 一键安装指令 wget http://fishros.com/install -O fishros && . fishros出现问题&#xff1a;docker pull 失败 网络不同&#xff0c;需要使用镜像源 按照如下步骤操作 sudo vi /etc/docker/dae…...

如何在网页里填写 PDF 表格?

有时候&#xff0c;你可能希望用户能在你的网站上填写 PDF 表单。然而&#xff0c;这件事并不简单&#xff0c;因为 PDF 并不是一种原生的网页格式。虽然浏览器可以显示 PDF 文件&#xff0c;但原生并不支持编辑或填写它们。更糟的是&#xff0c;如果你想收集表单数据&#xff…...

GitFlow 工作模式(详解)

今天再学项目的过程中遇到使用gitflow模式管理代码&#xff0c;因此进行学习并且发布关于gitflow的一些思考 Git与GitFlow模式 我们在写代码的时候通常会进行网上保存&#xff0c;无论是github还是gittee&#xff0c;都是一种基于git去保存代码的形式&#xff0c;这样保存代码…...

Python Einops库:深度学习中的张量操作革命

Einops&#xff08;爱因斯坦操作库&#xff09;就像给张量操作戴上了一副"语义眼镜"——让你用人类能理解的方式告诉计算机如何操作多维数组。这个基于爱因斯坦求和约定的库&#xff0c;用类似自然语言的表达式替代了晦涩的API调用&#xff0c;彻底改变了深度学习工程…...

逻辑回归暴力训练预测金融欺诈

简述 「使用逻辑回归暴力预测金融欺诈&#xff0c;并不断增加特征维度持续测试」的做法&#xff0c;体现了一种逐步建模与迭代验证的实验思路&#xff0c;在金融欺诈检测中非常有价值&#xff0c;本文作为一篇回顾性记录了早年间公司给某行做反欺诈预测用到的技术和思路。百度…...

基于PHP的连锁酒店管理系统

有需要请加文章底部Q哦 可远程调试 基于PHP的连锁酒店管理系统 一 介绍 连锁酒店管理系统基于原生PHP开发&#xff0c;数据库mysql&#xff0c;前端bootstrap。系统角色分为用户和管理员。 技术栈 phpmysqlbootstrapphpstudyvscode 二 功能 用户 1 注册/登录/注销 2 个人中…...

Docker拉取MySQL后数据库连接失败的解决方案

在使用Docker部署MySQL时&#xff0c;拉取并启动容器后&#xff0c;有时可能会遇到数据库连接失败的问题。这种问题可能由多种原因导致&#xff0c;包括配置错误、网络设置问题、权限问题等。本文将分析可能的原因&#xff0c;并提供解决方案。 一、确认MySQL容器的运行状态 …...