【数据结构初阶】二、 线性表里的顺序表

=========================================================================

相关代码gitee自取

C语言学习日记: 加油努力 (gitee.com)

 =========================================================================

接上期

【数据结构初阶】一. 复杂度讲解_高高的胖子的博客-CSDN博客

 =========================================================================

                     

1 . 线性表

               

线性表linear list)是n个具有相同特性的数据元素的有限序列

线性表是一种在实际中广泛使用的数据结构

常见线性表顺序表链表队列字符串...

顺序表示例:

              

              

线性表逻辑上线性结构,也就说是连续的一条直线

但是在物理结构上并不一定是连续的

线性表物理上存储时,通常以数组链式结构形式存储

链表示例:

         

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

             

2 . 顺序表

顺序表概念及结构:

               

顺序表一段物理地址连续的存储单元依次存储数据元素线性结构

一般情况下采用数组存储

数组上完成数据的增删查改

顺序表一般可以分为 静态顺序表动态顺序表

               

               

静态顺序表:使用定长数组存储元素

                

因为静态顺序表使用定长数组存储元素

对空间的运用不够灵活,可能造成空间浪费或不够的问题
所以在实际情况下静态顺序表并不常用不够实用

示例:

                    

                    

动态顺序表:使用动态开辟的数组存储元素

             

静态顺序表适用于确定知道需要存多少数据的场景

静态顺序表定长数组导致N定大了空间开多了浪费开少了不够用

所以现实中基本都是使用动态顺序表根据需要动态地分配空间大小

示例:

         

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

             

3 .接口实现(实现动态顺序表):

(详细解释在注释,代码分文件放最后)

                

数据结构可以管理数据

通过 增删改查 等操作就可以实现管理数据

              

现在有了动态顺序表后

就可以对其进行增删改查等操作实现动态顺序表

                      

                        

--------------------------------------------------------------------------------------------------------------------------

                  

                      

SLInit函数 -- 顺序表初始化

                      

                      

--------------------------------------------------------------------------------------------------------------------------

                  

                      

SLDestroy函数 -- 顺序表销毁

                      

                        

--------------------------------------------------------------------------------------------------------------------------

                  

                      

SLPrint函数 -- 测试函数

                      

                        

--------------------------------------------------------------------------------------------------------------------------

                  

                      

SLPushBack函数 -- 将值插入顺序表尾部(尾插)

尾插函数SLPushBack测试:

                      

                        

--------------------------------------------------------------------------------------------------------------------------

                  

                      

上面尾插需要考虑空间不够进行扩容

后面的头插同样也需要考虑

所以可以在顺序表实现文件设置一个内部函数SLCheckCapacity,

在需要的时候直接调用该函数进行扩容操作

↓↓↓↓↓

                 

SLCheckCapacity内部函数 -- 进行扩容操作

                      

                        

--------------------------------------------------------------------------------------------------------------------------

                  

                      

SLPopBack函数 -- 将值从顺序表尾部删除(尾删)

尾删函数SLPopBack测试:

                      

                        

--------------------------------------------------------------------------------------------------------------------------

                  

                      

SLPushFront函数 -- 将值插入顺序表头部(头插)

头插函数SLPushFront测试:

                      

                        

--------------------------------------------------------------------------------------------------------------------------

                  

                      

SLPopFront函数 -- 将值从顺序表头部删除(头删)

头删函数SLPopFront测试:

                      

                        

--------------------------------------------------------------------------------------------------------------------------

                  

                      

SLInsert函数 -- 在指定位置(pos)插入想要的值(x)

指定添加函数SLInsert测试:

             

这里写了指定位置插入SLInsert函数

可以想到其实 头插 尾插 也是可以用 SLInsert函数 实现的

所以可以在头插和尾插函数中复用 SLInsert函数减少代码量

↓↓↓↓↓

                  

复用SLInsert函数 -- 改写头插函数SLPushFront

                     

复用SLInsert函数 -- 改写尾插函数SLPushBack

                      

                        

--------------------------------------------------------------------------------------------------------------------------

                  

                      

上面SLInsert函数涉及了插入位置pos下标

有时在增删改查操作时,需要知道有效元素中某个元素的下标再进行操作,

所以我们可以定义一个函数SLFind查找该元素的下标

↓↓↓↓↓

                 

SLFind函数 -- 查找x这个值在顺序表中的下标是多少

查找函数SLFind测试:

                      

                        

--------------------------------------------------------------------------------------------------------------------------

                  

                      

SLErase函数 -- 删除指定位置(pos)的值

删除指定位置函数SLErase测试:

                   

完成指定删除SLErase函数

头删 尾删 函数中也可以进行复用 SLErase函数 减少代码量

↓↓↓↓↓

                  

用SLErase函数 -- 改写头删函数SLPopFront

                     

用SLErase函数 -- 改写尾删函数SLPopBack

                      

                        

--------------------------------------------------------------------------------------------------------------------------

                  

                      

SLModify函数 -- 把某个位置(pos)的值修改为某值(x)

修改函数SLModify测试:

          

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

             

4 . 对应代码

SeqList.h -- 顺序表头文件

#pragma once定义一个静态顺序表:使用定长数组存储元素
因为静态顺序表使用定长数组存储元素,对空间的运用不够灵活
所以在实际情况下,静态顺序表并不常用(不够实用)
//
//#define N 1000  //“表”的大小的值
//typedef int SLDataType;  //定义顺序表中存储的类型,这里是int类型
//
//struct SeqList
//{
//	SLDataType a[N]; //定义表的大小
//	int size; //记录表中存储了多少个有效数据
//};//将需要的头文件都包含在 SeqList.h 头文件中
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>//定义一个动态顺序表:使用动态开辟的数组存储元素
typedef int SLDataType;  //定义顺序表中存储的类型,这里是int类型typedef struct SeqList
{//定义一个顺序表类型的指针,指向动态开辟的数组SLDataType* a; int size; //记录表中存储了多少个有效数据int capactity; //容量空间的大小
}SL;//数据结构 --> 管理数据 --> 增删查改//顺序表初始化  --  头文件中声明
void SLInit(SL* ps); //顺序表销毁 --  头文件中声明
//内存是动态开辟地,不销毁的话可能会导致内存泄漏)
void SLDestroy(SL* ps);//写一个测试函数(声明),方便检查各步骤有没有问题:
void SLPrint(SL* ps);//尾插(声明) -- 将值插入顺序表尾部:
void SLPushBack(SL* ps, SLDataType x);//尾删(声明) -- 将值从顺序表尾部删除:
void SLPopBack(SL* ps);//头插(声明) -- 将值插入顺序表头部:
void SLPushFront(SL* ps, SLDataType x);//头删(声明) -- 将值从顺序表头部删除:
void SLPopFront(SL* ps);//在指定位置(pos)插入想要的值(x)
void SLInsert(SL* ps, int pos, SLDataType x);//查找x这个值在顺序表中的下标是多少:
int SLFind(SL* ps, SLDataType x); //返回找到的下标//删除指定位置(pos)的值:
void SLErase(SL* ps, int pos);//把某个位置(pos)的值修改为某值(x)
void SLModify(SL* ps, int pos, SLDataType x);

                        

--------------------------------------------------------------------------------------------------------------------------

                  

                      

SeqList.c -- 顺序表实现文件

#define _CRT_SECURE_NO_WARNINGS 1//包含我们写的 SeqList.h 头文件
#include "SeqList.h"//顺序表初始化 -- 实现
void SLInit(SL* ps)
{//assert断言,防止接收空指针:assert(ps);//初始化顺序表类型指针//初始化时要先开辟一些动态空间://开辟的空间为顺序表类型,大小为4个顺序表类型的大小ps->a = (SLDataType*)malloc(sizeof(SLDataType)*4); //顺序表作为一个独立的程序,之后可能会应用于其他程序,//所以要对开辟的动态空间进行检查:if (ps->a == NULL){//可能开辟的空间过大 或 前面开辟太多空间不够再开辟perror("malloc failed");  //打印错误//让程序以异常的形式结束程序//和 return 不同,return后主函数还会继续进行exit(-1);}//将顺序表中的有效数据初始化为0:ps->size = 0;//将已动态开辟的容量空间初始化为4:ps->capactity = 4;
}//顺序表销毁 -- 实现
//内存是动态开辟地,不销毁的话可能会导致内存泄漏)
void SLDestroy(SL* ps)
{//assert断言,防止接收空指针:assert(ps);//释放前面开辟的动态空间:free(ps->a);//将释放的指针置为空指针:ps->a = NULL;//将已开辟的动态空间置为0,顺序表有效数据也置为0ps->capactity = ps->size = 0;
}//写一个测试函数(实现),方便检查各步骤有没有问题:
void SLPrint(SL* ps)
{//assert断言,防止接收空指针:assert(ps);//打印动态顺序表现有的有效数据:for (int i = 0; i < ps->size; i++){printf("%d ", ps->a[i]);}//打印完当前动态顺序表有效数据后进行换行:printf("\n");
}//在顺序表实现文件中设置一个内部函数SLCheckCapacity,
//在需要的时候直接调用该函数进行扩容操作
void SLCheckCapacity(SL* ps)
{//assert断言,防止接收空指针:assert(ps);//判断开辟的空间是否已满,满了再开辟:if (ps->size == ps->capactity)//顺序表有效个数 等于 已开辟容量空间{//使用 realloc函数 进行扩容,每次扩容2倍:SLDataType* tmp = (SLDataType*)realloc(ps->a, ps->capactity * 2 * (sizeof(SLDataType)));// realloc 是把空间扩容到第二个参数的大小,而不是直接把空间扩容第二个参数的大小//同样进行检验:if (tmp == NULL){//打印错误:perror("realloc failed");//出现错误直接终止程序:exit(-1);}//realloc函数,有两种扩容情况:一种是原地扩容,另一种是异地扩容//原地扩容:扩容时看原空间后的内容有没有分配给别人,如果没有则把原空间后面的空间标记出来进行扩容,返回原空间的地址//异地扩容:如果扩容时原空间后面的内容已被分配,则另找一个足够原空间扩容后的空间进行存放,//		   原本的数据都搬到这个空间来,原空间会被释放,返回这个新空间的地址。//所以使用 realloc函数 扩容后,不要对原空间指针进行释放,//如果realloc执行后是原地扩容返回原空间指针,扩容后后对原空间指针释放就会出问题//把扩容返回的指针赋给原指针:ps->a = tmp;//将已动态开辟的容量空间置为原来的2倍:ps->capactity *= 2;}
}//尾插(实现) -- 将值插入顺序表尾部:
void SLPushBack(SL* ps, SLDataType x)
{//assert断言,防止接收空指针:assert(ps);调用内部函数进行扩容操作://SLCheckCapacity(ps);空间容量足够后将要插入尾部的值插入://ps->a[ps->size] = x; 因为下标从0开始,所以size的值会等于现有元素下一位的下标//ps->size++; //尾部插入元素后,更新顺序表中有效数据个数//复用SLInsert函数 -- 改写尾插函数SLPushBackSLInsert(ps, ps->size, x); //在size位置插入就相当于尾插
}//尾删(实现) -- 将值从顺序表尾部删除:
void SLPopBack(SL* ps)
{//assert断言,防止接收空指针:assert(ps);检查一下:如果有效数据size等于0,则不能继续删除了防止越界,可能一直删除到空间外了导致越界//检查方法一:太“温柔”,返回后不知道自己错了if (ps->size == 0){return; //直接返回 即可}//检查方法二:使用断言,错误了会直接报错并给出错误信息//assert(ps->size > 0); //顺序表中有效数据大于0才进行下面的操作直接有效数据size--即可尾插是也是用size插入的,所以下次添加时直接就覆盖了原来值//ps->size--;不能局部释放,不能说不要末尾的值就把末尾的这个空间直接释放掉C++有个规定,malloc一次就要free一次,要free释放的话只能整体释放顺序表的物理内存是连续的,释放空间是不能“分期”的//复用SLErase函数 -- 改写尾删函数SLPopBackSLErase(ps, ps->size-1); //size-1 就是最末元素下标
}//头插(实现) -- 将值插入顺序表头部:
void SLPushFront(SL* ps, SLDataType x)
{//assert断言,防止接收空指针:assert(ps);调用内部函数进行扩容操作://SLCheckCapacity(ps);将现有有效数据往后移一位,让出头位置://int end = ps->size - 1; size-1 有效个数-1,就相当于当前最后一个元素的下标//while (end >= 0)//	//使用while循环循环移动各个有效元素,一直移到下标为0的元素//{//	ps->a[end + 1] = ps->a[end]; //end下标元素 移到 下一位上//	--end; //改变下标//}将要插入头部的元素x插入头部://ps->a[0] = x;有效个数加一://ps->size++;Capacity在扩容函数SLCheckCapacity中就修改好了//复用SLInsert函数 -- 改写头插函数SLPushFrontSLInsert(ps, 0, x); //在0位置插入就相当于头插
}//头删(实现) -- 将值从顺序表头部删除:
void SLPopFront(SL* ps)
{//assert断言,防止接收空指针:assert(ps);因为要将头部的有效元素删除,所以直接把第一个有效元素后面的其他元素往前移一位就行了,覆盖掉第一个元素先进行断言检查,防止没有元素还进行删除://assert(ps->size > 0);//int begin = 1; //从下标为1的元素开始往前移,把下标为0的元素覆盖//while (begin < ps->size)//	//只要begin还小于有效元素个数就继续往前移//	//因为是从下标为1的元素开始移动,//	//所以最后就只有下标为0的元素没动//{//	//把当前begin下标的元素往前挪一位://	ps->a[begin - 1] = ps->a[begin]; //	//当前begin下标元素移动后,begin++继续移动下一位://	++begin;//}//因为第一个元素被覆盖,所以有效元素size--//ps->size--;//复用SLErase函数 -- 改写头删函数SLPopFrontSLErase(ps, 0); //头元素下标是0
}//在指定位置(pos)插入想要的值(x)
void SLInsert(SL* ps, int pos, SLDataType x)
{//先使用assert检查pos是否合法://在pos位置插入一个值后,顺序表还得是连续的assert(pos >= 0 && pos <= ps->size);//pos等于0 -- 相等于头插//pos等于size -- 相等于尾插//使用SLCheckCapacity进行扩容操作:SLCheckCapacity(ps);//定义一个变量end,对应要移动元素的下标int end = ps->size - 1; //一开始对应最后一个元素的下标while (end >= pos)//只要end下标对应的元素还在pos下标元素的右边//就把“end元素”向右移,移到pos下标无元素{//把“end元素”向右移ps->a[end + 1] = ps->a[end];//移动下标进行写一个元素的移动--end;}//让出位置后,将接收的x插入pos位置:ps->a[pos] = x;//有效元素+1:ps->size++;
}//查找x这个值在顺序表中的下标是多少:
int SLFind(SL* ps, SLDataType x) //返回找到的下标
{//assert断言,防止接收空指针:assert(ps);//数据量不大的话直接暴力查找吧:for (int i = 0; i < ps->size; i++)//有几个有效元素就循环几次:{if (ps->a[i] == x)//该下标元素等于要找的值x则返回当前下标:{return i;}}return -1; //表未找到该元素下标
}//删除指定位置(pos)的值:
void SLErase(SL* ps, int pos)
{//同样先使用assert检查pos是否合法://这里检查条件pos不能像SLInsert一样等于size//因为size空了能插入(尾插),但不能删除assert(pos >= 0 && pos < ps->size);//指定删除和头删的思路类似,//只要把pos后面的值往前覆盖,覆盖掉pos的值就好了:int begin = pos + 1; //从pos+1的位置往前挪while (begin < ps->size)//一直移到size为止(不包括size位置){ps->a[begin - 1] = ps->a[begin]; //往前挪++begin; //挪完继续挪下一个 }ps->size--; //覆盖掉pos位置的值后,有效数字减一
}//把pos位置的值修改为x
void SLModify(SL* ps, int pos, SLDataType x)
{//同样先使用assert断言检查pos是否合法:assert(pos >= 0 && pos < ps->size);//进行修改:ps->a[pos] = x;
}

                        

--------------------------------------------------------------------------------------------------------------------------

                  

                      

test.c -- 测试函数

#define _CRT_SECURE_NO_WARNINGS 1//包含我们写的 SeqList.h 头文件
#include "SeqList.h"//分组测试,测试不同的函数--SLPushBack 和 SLPopBack 函数
void TestSeqList1()
{SL sl;  //创建顺序表类型变量//使用 SLInit函数 初始化顺序表类型变量//注意传递的是变量的地址,防止形参改变实参不改变SLInit(&sl);//使用尾插函数SLPushBack:SLPushBack(&sl, 1);SLPushBack(&sl, 2);SLPushBack(&sl, 3);SLPushBack(&sl, 4);//此时再调用会进行扩容:SLPushBack(&sl, 5);SLPushBack(&sl, 6);//调用测试函数SPrint查看是否插入成功:SLPrint(&sl);//测试尾删函数SLPopBack:SLPopBack(&sl);SLPopBack(&sl);//调用测试函数SPrint查看是否“删除”成功:SLPrint(&sl);//测试完后使用SLDestroy函数销毁顺序表:SLDestroy(&sl);
}//分组测试,测试不同的函数--SLPushFront函数
void TestSeqList2()
{SL sl;  //创建顺序表类型变量//使用 SLInit函数 初始化顺序表类型变量//注意传递的是变量的地址,防止形参改变实参不改变SLInit(&sl);//使用尾插函数SLPushBack:SLPushBack(&sl, 1);SLPushBack(&sl, 2);SLPushBack(&sl, 3);SLPushBack(&sl, 4);//此时再调用会进行扩容:SLPushBack(&sl, 5);SLPushBack(&sl, 6);//调用测试函数SPrint查看是否插入成功:SLPrint(&sl);//测试头插函数SLPushFront:SLPushFront(&sl, 10);SLPushFront(&sl, 20);//调用测试函数SPrint查看是否“删除”成功:SLPrint(&sl);//测试完后使用SLDestroy函数销毁顺序表:SLDestroy(&sl);
}//分组测试,测试不同的函数--SLPopFront函数
void TestSeqList3()
{SL sl;  //创建顺序表类型变量//使用 SLInit函数 初始化顺序表类型变量//注意传递的是变量的地址,防止形参改变实参不改变SLInit(&sl);//使用尾插函数SLPushBack:SLPushBack(&sl, 1);SLPushBack(&sl, 2);SLPushBack(&sl, 3);SLPushBack(&sl, 4);//此时再调用会进行扩容:SLPushBack(&sl, 5);SLPushBack(&sl, 6);//调用测试函数SPrint查看是否插入成功:SLPrint(&sl);//测试头删函数SLPopFront:SLPopFront(&sl);SLPopFront(&sl);//调用测试函数SPrint查看是否“删除”成功:SLPrint(&sl);//测试完后使用SLDestroy函数销毁顺序表:SLDestroy(&sl);
}//分组测试,测试不同的函数--SLInsert函数
void TestSeqList4()
{SL sl;  //创建顺序表类型变量//使用 SLInit函数 初始化顺序表类型变量//注意传递的是变量的地址,防止形参改变实参不改变SLInit(&sl);//使用尾插函数SLPushBack:SLPushBack(&sl, 1);SLPushBack(&sl, 2);SLPushBack(&sl, 3);SLPushBack(&sl, 4);//此时再调用会进行扩容:SLPushBack(&sl, 5);SLPushBack(&sl, 6);//调用测试函数SPrint查看是否插入成功:SLPrint(&sl);//测试指定增加函数SLInsert:SLInsert(&sl, 2, 100);//调用测试函数SPrint查看是否“删除”成功:SLPrint(&sl);//int x;//scanf("%d", &x);//int pos = SLFind(&sl, x);//if (pos != -1)//{//	SLInsert(&sl, pos, x * 10);//}//SLPrint(&sl);//测试完后使用SLDestroy函数销毁顺序表:SLDestroy(&sl);
}//分组测试,测试不同的函数--SLFind函数
void TestSeqList5()
{SL sl;  //创建顺序表类型变量//使用 SLInit函数 初始化顺序表类型变量//注意传递的是变量的地址,防止形参改变实参不改变SLInit(&sl);//使用尾插函数SLPushBack:SLPushBack(&sl, 1);SLPushBack(&sl, 2);SLPushBack(&sl, 3);SLPushBack(&sl, 4);//此时再调用会进行扩容:SLPushBack(&sl, 5);SLPushBack(&sl, 6);//调用测试函数SPrint查看是否插入成功:SLPrint(&sl);//测试指定增加函数SLFind:int pos = SLFind(&sl, 2);printf("2在元素中是第%d个元素", pos+1);//测试完后使用SLDestroy函数销毁顺序表:SLDestroy(&sl);
}//分组测试,测试不同的函数--SLErase函数
void TestSeqList6()
{SL sl;  //创建顺序表类型变量//使用 SLInit函数 初始化顺序表类型变量//注意传递的是变量的地址,防止形参改变实参不改变SLInit(&sl);//使用尾插函数SLPushBack:SLPushBack(&sl, 1);SLPushBack(&sl, 2);SLPushBack(&sl, 3);SLPushBack(&sl, 4);//此时再调用会进行扩容:SLPushBack(&sl, 5);SLPushBack(&sl, 6);//调用测试函数SPrint查看是否插入成功:SLPrint(&sl);int x;scanf("%d", &x);//配合SLFind函数,找到顺序表中某个值的下标int pos = SLFind(&sl, x);//再使用SLErase函数通过下标删除该值if (pos != -1){SLErase(&sl, pos);}SLPrint(&sl);//测试完后使用SLDestroy函数销毁顺序表:SLDestroy(&sl);
}//分组测试,测试不同的函数--SLModify函数
void TestSeqList7()
{SL sl;  //创建顺序表类型变量//使用 SLInit函数 初始化顺序表类型变量//注意传递的是变量的地址,防止形参改变实参不改变SLInit(&sl);//使用尾插函数SLPushBack:SLPushBack(&sl, 1);SLPushBack(&sl, 2);SLPushBack(&sl, 3);SLPushBack(&sl, 4);//此时再调用会进行扩容:SLPushBack(&sl, 5);SLPushBack(&sl, 6);//调用测试函数SPrint查看是否插入成功:SLPrint(&sl);//测试指定增加函数SLInsert:SLModify(&sl, 2, 100);//调用测试函数SPrint查看是否“删除”成功:SLPrint(&sl);//测试完后使用SLDestroy函数销毁顺序表:SLDestroy(&sl);
}//菜单:
void menu()
{printf("********************************\n");printf("1、尾插			2、头插\n");printf("3、头删			4、尾删\n");printf("7、打印			-1、退出\n");printf("********************************\n");
}int main()
{//先创建一个顺序表:SL sl;//再对其进行初始化:SLInit(&sl);//创建一个变量接收菜单选项:int option = 0;do{//使用菜单:menu();//打印提示信息:printf("请选择想要进行的操作的序号:>");//接收序号:scanf("%d", &option);printf("\n");if (option == 1){printf("请依次输入你要插入的数据个数:>");int n = 0; //接收数据个数scanf("%d", &n); //接收数据个数printf("\n");printf("请依次输入你要插入的数据\n");//知道数据个数后,直接使用for循环循环接收数据int x = 0;for (int i = 0; i < n; i++){scanf("%d", &x);SLPushBack(&sl, x);}}else if (option == 7){SLPrint(&sl);}} while (option != -1);//最后销毁顺序表:SLDestroy(&sl);//TestSeqList1();//TestSeqList2();//TestSeqList3();//TestSeqList4();//TestSeqList5();//TestSeqList6();//TestSeqList7();return 0;
}

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

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

相关文章

WMS仓储管理系统的功能与WCS系统有什么区别

在物流行业的现代化管理中&#xff0c;WMS仓储管理系统和WCS仓库控制系统是两个重要的组成部分。虽然它们都是用于仓库管理的软件系统&#xff0c;但是它们的功能和应用场景有很大的区别。本文我们将详细阐述这两者的功能和区别。 一、WMS仓储管理系统 WMS是一种软件系统&…

科技资讯|苹果Vision Pro获得被动冷却系统及数字表冠控制界面专利

据patentlyapple报道&#xff0c;美国专利商标局正式授予苹果一项与头戴式设备&#xff08;Apple Vision Pro&#xff09;相关的专利11751366&#xff0c;该设备可以提供被动冷却系统&#xff0c;利用光学组件的表面来管理热量&#xff0c;而不会对用户显示的视觉信息产生不利影…

计算机竞赛 基于深度学习的动物识别 - 卷积神经网络 机器视觉 图像识别

文章目录 0 前言1 背景2 算法原理2.1 动物识别方法概况2.2 常用的网络模型2.2.1 B-CNN2.2.2 SSD 3 SSD动物目标检测流程4 实现效果5 部分相关代码5.1 数据预处理5.2 构建卷积神经网络5.3 tensorflow计算图可视化5.4 网络模型训练5.5 对猫狗图像进行2分类 6 最后 0 前言 &#…

[C++]杨辉三角

目录 题目 解题思路 代码实现 获取数字 打印函数 主函数 全部代码 运行结果 题目 给定一个非负整数numRows &#xff0c;生成「杨辉三角」的前numRows行。 在「杨辉三角」中&#xff0c;每个数是它左上方和右上方的数的和。 解题思路 第k列的第i个数字的值第k-1列的(…

鸿鹄工程项目管理系统em Spring Cloud+Spring Boot+前后端分离构建工程项目管理系统

Java版工程项目管理系统 Spring CloudSpring BootMybatisVueElementUI前后端分离 功能清单如下&#xff1a; 首页 工作台&#xff1a;待办工作、消息通知、预警信息&#xff0c;点击可进入相应的列表 项目进度图表&#xff1a;选择&#xff08;总体或单个&#xff09;项目显示…

Linux编辑器vim

目录 一、vim的几种模式 1、命令模式 2、编辑/插入模式 3、底行模式 ①增加行号 ②分屏操作 ③不退出vim执行命令 4、替换模式 二、vim的常见命令 1、yy命令 2、p命令 3、dd命令 4、u命令 5、Ctrl r命令 6、shirtg命令 7、gg命令 8、shirt6命令 9、shirt4命…

查看视频文件关键帧间隔

一、Elecard StreamEye Tools拖放视频文件查看。 红的是I帧&#xff1b;蓝的是P帧&#xff1b;绿的是B帧。 二、ffprobe -show_streams统计。 1、统计视频关键帧、非关键帧 ffprobe.exe -i 1.mp4 -show_streams v -show_packets -print_format json > d:\1.json 再统计1.j…

[SSM]MyBatisPlus拓展

五、拓展篇 5.1逻辑删除 在电商网站中&#xff0c;我们会上架很多商品&#xff0c;这些商品下架以后&#xff0c;我们如果将这些商品从数据库中删除&#xff0c;那么在年底统计商品的时候&#xff0c;这个商品要统计的&#xff0c;所以这个商品信息我们是不能删除的。 如果商城…

分布式锁怎么抗高并发 redis

比如&#xff0c;多个人下单某一个商品 怎么处理 分段加锁 合并扣减。 这里首先要让redis是集群&#xff0c;避开单机性能问题。 大概意思就是将商品分摊到多个服务器上&#xff0c;这样就减轻了单台的压力

EXPLAIN概述与字段剖析

6. 分析查询语句&#xff1a;EXPLAIN(重点) 6.1 概述 定位了查询慢的sQL之后&#xff0c;我们就可以使用EXPLAIN或DESCRIBE 工具做针对性的分析查询语句。DESCRIBE语句的使用方法与EXPLAIN语句是一样的&#xff0c;并且分析结果也是一样的。 MySQL中有专门负责优化SELECT语句…

Alins - 化繁为简、极致优雅的WebUI框架

最近造了个js框架 Alins&#xff0c;分享一下&#xff1a; &#x1f680; Alins: 最纯粹优雅的WebUI框架 English | 文档 | 演练场 | 更新日志 | 反馈错误/缺漏 | Gitee | 留言板 0 简介 0.1 前言 Alins是一款极致纯粹、简洁、优雅的Web UI框架。秉持0-API、Less is More 的…

【操作系统】电脑上没有IIS怎么办

文章目录 前言一、查看二、解决 前言 有的新机刚开始在计算机-管理-服务下没有IIS网络服务怎么办。 一、查看 桌面计算机/此电脑 鼠标右键&#xff1a;管理 服务和应用 发现没有IIS 二、解决 控制面板 程序和功能 启动或关闭Windows功能 IIS相关的所有功能选中&#xff…

2023年9月8日

1> 自行封装一个栈的类&#xff0c;包含私有成员属性&#xff1a;栈的数组、记录栈顶的变量 成员函数完成&#xff1a;构造函数、析构函数、拷贝构造函数、入栈、出栈、清空栈、判空、判满、获取栈顶元素、求栈的大小 #include <iostream>using namespace std;class…

selenium的Chrome116版驱动下载

这里写自定义目录标题 下载地址https://googlechromelabs.github.io/chrome-for-testing/#stable 选择chromedriver 对应的平台和版本 国内下载地址 https://download.csdn.net/download/dongtest/88314387

WorkPlus AI助理,基于ChatGPT的企业级知识问答机器人

随着人工智能技术的发展&#xff0c;WorkPlus AI助理以ChatGPT对话能力为基础&#xff0c;将企业数据与人工智能相结合&#xff0c;推出了面向企业的知识问答机器人。这一创新性的解决方案帮助企业高效管理和利用自身的知识资产&#xff0c;助力企业级人工智能的构建。与传统的…

【MySQL】数据库的约束

MySQL 数据库的约束 文章目录 MySQL 数据库的约束01 数据库的约束1.1 约束类型1.1.1 NOT NULL1.1.2 UNIQUE1.1.3 DEFAULT1.1.4 PRIMARY KEY1.1.5 FOREIGN KEY1.1.6 CHECK 继上文 MySQL基础&#xff08;一&#xff09;&#xff0c; MySQL基础&#xff08;二&#xff09;&#…

详解初阶数据结构之顺序表(SeqList)——单文件文件实现SeqList的增删查改

目录 一、线性表 二、顺序表 2.1概念及结构 2.2接口实现 2.3动态顺序表的创建 2.3动态顺序表的初始化 2.3.1传值初始化 2.3.2传址初始化 2.4动态顺序表的清空 2.5动态顺序表的扩容 2.6动态顺序表内容的打印 三、动态顺序表的使用 3.1尾插尾删 3.1.1尾插 3.1.2尾删…

基于Bert+Attention+LSTM智能校园知识图谱问答推荐系统——NLP自然语言处理算法应用(含Python全部工程源码及训练模型)+数据集

目录 前言总体设计系统整体结构图系统流程图 运行环境Python 环境服务器环境 模块实现1. 构造数据集2. 识别网络3. 命名实体纠错4. 检索问题类别5. 查询结果 系统测试1. 命名实体识别网络测试2. 知识图谱问答系统整体测试 工程源代码下载其它资料下载 前言 这个项目充分利用了…

linux编辑器-vim

1.vim是什么 vim 是从 vi 发展出来的一个文本编辑器。代码补全、编译及错误跳转等方便编程的功能特别丰富&#xff0c;在程序员中被广泛使用。简单的来说&#xff0c; vi 是老式的字处理器&#xff0c;不过功能已经很齐全了&#xff0c;但是还是有可以进步的地方。 vim 则可以…

前端uniapp块样式写法

<template><view class"block"><view class"block_box"><view class"block_box_content"><view class"block_box_left">左边</view><view class"block_box_right">右边</view…