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

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

相关代码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.rhkb.cn/news/125724.html

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

相关文章

Ansys Zemax | 手机镜头设计 - 第 3 部分:使用 STAR 模块和 ZOS-API 进行 STOP 分析

本文是 3 篇系列文章的一部分&#xff0c;该系列文章将讨论智能手机镜头模组设计的挑战&#xff0c;从概念、设计到制造和结构变形的分析。本文是三部分系列的第三部分。它涵盖了使用 Ansys Zemax OpticStudio Enterprise 版本提供的 STAR 技术对智能手机镜头进行自动的结构、热…

Kubectl 使用详解——k8s陈述式资源管理

目录 一、kubectl 简介 二、kubectl 的使用 1.基础用法 &#xff08;1&#xff09;配置kubectl自动补全 &#xff08;2&#xff09;查看版本信息 &#xff08;3&#xff09;查看资源对象信息 &#xff08;4&#xff09;查看集群信息 &#xff08;5&#xff09;查看日志…

手敲Cocos简易地图编辑器:人生地图是一本不断修改的书,每一次编辑都是为了克服新的阻挡

引言 本系列是《8年主程手把手打造Cocos独立游戏开发框架》&#xff0c;欢迎大家关注分享收藏订阅。 在上一篇文章&#xff0c;笔者给大家讲解了在Cocos独立游戏开发框架中&#xff0c;如何自定义实现Tile地图管理器&#xff0c;成功地在游戏中优化加载一张特大的地图。接下来…

uni-app 之 获取网络列表数据

uni-app 之 获取网络列表数据 image.png <template><!-- vue2的<template>里必须要有一个盒子&#xff0c;不能有两个&#xff0c;这里的盒子就是 view--><view>--- uni.request 网络请求API接口 ---<view v-for"(item) in caturl" :key&…

git 远程多分支,本地如何切换分支

1、git clone url 先clone 项目&#xff0c;git branch -a 查看所有分支&#xff0c;发现有多个远程分支 2、假如想在 remote 分支工作&#xff0c;但是本地还没有 remote 分支&#xff0c;可以先输入命令&#xff1a; git checkout &#xff0c;不要按回车键&#xff0c;按…

JAVA毕业设计097—基于Java+Springboot+Vue+uniapp的医院挂号小程序系统(源码+数据库)

基于JavaSpringbootVueuniapp的医院挂号小程序系统(源码数据库)097 一、系统介绍 本系统前后端分离(网页端和小程序端都有) 本系统分为管理员、医院、用户三种角色(角色菜单可自行分配) 用户功能&#xff1a; 注册、登录、医院搜索、最新资讯、医生搜索、挂号预约、挂号记…

如何在Windows中使用C#填写和提取PDF表单

如何在Windows中使用C#填写和提取PDF表单 PDF表单不仅允许用户填写和提交数据&#xff0c;也允许用户创建各种表单域收集用户的数据&#xff0c;并通过提取表单字段值&#xff0c;将收集和合并提交的数据进一步分析或处理。PDF通过电子方式填写、保存和共享的形式&#xff0c;…

1.8 工程相关解析(各种文件,资源访问

目录 1.8 工程相关解析(各种文件&#xff0c;资源访问) 分类 Android 基础入门教程 本节引言&#xff1a; 1.工程项目结构解析&#xff1a; 1.res资源文件夹介绍&#xff1a; 2.如何去使用这些资源 2.深入了解三个文件&#xff1a; MainActivity.java&#xff1a; 布局…

【UE】材质描边、外发光、轮廓线

原教学视频链接&#xff1a; ue4 材质描边、外发光、轮廓线_哔哩哔哩_bilibili 步骤 1. 首先新建一个材质&#xff0c;这里命名为“Mat_outLine” 在此基础上创建一个材质实例 2. 在视口中添加一个后期处理体积 设置后期处理体积为无限范围 点击添加一个数组 选择“资产引用”…

牛客网——BM62 斐波那契数列

class Solution { public:/*** 代码中的类名、方法名、参数名已经指定&#xff0c;请勿修改&#xff0c;直接返回方法规定的值即可** * param n int整型 * return int整型*/int Fibonacci(int n) {// write code hereif(n0) //考虑第0项return 0;else if(n1||n2)return 1;else…

深入了解 Axios 的 put 请求:使用技巧与最佳实践

在前端开发中&#xff0c;我们经常需要与后端服务器进行数据交互。其中&#xff0c;PUT 请求是一种常用的方法&#xff0c;用于向服务器发送更新或修改数据的请求。通过发送 PUT 请求&#xff0c;我们可以更新服务器上的资源状态。 Axios 是一个流行的 JavaScript 库&#xff0…

开源知识库平台Raneto

什么是 Raneto &#xff1f; Raneto 是一个开源知识库平台&#xff0c;它使用静态 Markdown 文件来支持您的知识库。 官方提供了 doc & demo 网站&#xff0c;即是帮助文档&#xff0c;也是个 demo&#xff0c;地址&#xff1a;https://docs.raneto.com 准备 项目使用con…

微服务井喷时代,我们如何规模化运维?

随着云原生技术发展及相关技术被越来越多运用到公司生产实践当中&#xff0c;有两种不可逆转的趋势&#xff1a; 1、微服务数量越来越多。原来巨型单体服务不断被拆解成一个个微服务&#xff0c;在方便功能复用及高效迭代的同时&#xff0c;也给运维带来了不少挑战&#xff1a;…

pytorch学习——LSTM和GRU

参考书籍&#xff1a;https://zh-v2.d2l.ai/chapter_recurrent-modern/lstm.html 参考论文&#xff1a; https://colah.github.io/posts/2015-08-Understanding-LSTMs/ 简介&#xff1a; LSTM&#xff08;长短期记忆网络&#xff09;和GRU&#xff08;门控循环单元&#xff09;…

Yolov5 中添加注意力机制 CBAM

Yolov5 中添加注意力机制 CBAM 1. CBAM1.1 Channel Attention Module1.2 Spatial Attention Module1.3 Channel attention 和 Spatial attention 如何去使用 2. 在Yolov5中添加CBAM模块2.1 修改common.py 文件2.2 修改yolo.py 文件2.3 修改网络配置yolov5x-seg.yaml文件 3. 训练…

C# WPF 自己写的一个模拟病毒传播的程序,有可视化

源代码: https://github.com/t39q/VirusSpread 主要代码 using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks;namespace VirusSpread.Bu…

LeetCode-17-电话号码的字母组合

一&#xff1a;题目描述&#xff1a; 给定一个仅包含数字 2-9 的字符串&#xff0c;返回所有它能表示的字母组合。答案可以按 任意顺序 返回。 给出数字到字母的映射如下&#xff08;与电话按键相同&#xff09;。注意 1 不对应任何字母。 二&#xff1a;示例与提示 示例 1:…

【2023高教社杯】C题 蔬菜类商品的自动定价与补货决策 问题分析、数学模型及python代码实现

【2023高教社杯】C题 蔬菜类商品的自动定价与补货决策 1 题目 C题蔬菜类商品的自动定价与补货决策 在生鲜商超中&#xff0c;一般蔬菜类商品的保鲜期都比较短&#xff0c;且品相随销售时间的增加而变差&#xff0c; 大部分品种如当日未售出&#xff0c;隔日就无法再售。因此&…

js函数变量提升理解

var n 10function fn() {// var n 20function f() {// 没用var声明&#xff0c;去外层寻找n,直到找到windows为止&#xff0c;找到的话用的就是哟个全局变量&#xff0c;会改变原始全局变量的值n;console.log(n)}var nn 20f()console.log(n);return f}var x fn()// 会在上一…

爱胜品YPS-1133DN系列打印机网络驱动安装的一点小经验

爱胜品YPS-1133DN打印机基本参数&#xff1a; 项目 详细参数 品牌 ICSP爱胜品 外观配色 上灰下白经典实用设计 打印速度 33ppm&#xff08;A4&#xff09;、35ppm&#xff08;Letter&#xff09;、58ppm&#xff08;A5&#xff09; 首页打印时间 ≤8秒 最大月打印量 …