数据结构:手撕代码——顺序表

目录

 

1.线性表

2.顺序表

2.1顺序表的概念

2.2动态顺序表实现

 2.2-1 动态顺序表实现思路

2.2-2 动态顺序表的初始化

 2.2-3动态顺序表的插入

检查空间

 尾插

头插 

中间插入 

2.2-4 动态顺序表的删除 

尾删

头删 

中间删除 

2.2. 5 动态顺序表查找与打印、销毁

查找

打印 

销毁 

 2.2 6 测试动态顺序表


1.线性表

    线性表(linear list)是n个具有相同特性的数据元素的有限序列。例如我们有一个数组,这个数组中的元素都占相同大小的内存,都具有相同的类型,而它们也按顺序排列的。线性表是一种在实际中广泛使用的数据结构,常见的线性表:顺序表、链表、栈、队列、字符串...

     线性表在逻辑上是线性结构,也就说是连续的一条直线。但是在物理结构上并不一定是连续的,线性表在物理上存储时,通常以数组和链式结构的形式存储。什么意思呢?逻辑结构可以看作我们把它想象成一个排列有序的数组:

  

物理结构就是这个表实际在内存的结构,它有可能是一个排列有序的数组,但是更大的可能是用指针连起来的无序的一块块空间:

2.顺序表

2.1顺序表的概念

    顺序表是线性表的其中一种。它是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储。在数组上完成数据的增删查改。

顺序表一般可以分为:
1. 静态顺序表:使用定长数组存储元素。

2. 动态顺序表:使用动态开辟的数组存储。

     那么二者哪个更具有优势呢?答案是动态顺序表,如果我们使用静态顺序表去存储某个app的用户数据,那么我们该用多少空间呢,如果空间太少,我们就会丢失一部分用户的数据,如果空间太大,又会浪费内存,而使用动态顺序表则不用考虑这两个问题,如果我们空间太小就增加内存,而一开始我们不会开辟太大的内存,所以不用担心空间浪费的问题,所以我们本期就要用代码实现动态顺序表。

2.2动态顺序表实现

  我们要实现顺序表,需要实现它的增删查改等功能:

typedef int SLDataType;
// 顺序表的动态存储
typedef struct SeqList
{
SLDataType* array; // 指向动态开辟的数组
size_t size ;
// 有效数据个数
size_t capicity ;
// 容量空间的大小
}SeqList;
// 基本增删查改接口
// 顺序表初始化
void SeqListInit(SeqList* psl);
// 检查空间,如果满了,进行增容
void CheckCapacity(SeqList* psl);
// 顺序表尾插
void SeqListPushBack(SeqList* psl, SLDataType x);
// 顺序表尾删
void SeqListPopBack(SeqList* psl);
// 顺序表头插
void SeqListPushFront(SeqList* psl, SLDataType x);
// 顺序表头删
void SeqListPopFront(SeqList* psl);
// 顺序表查找
int SeqListFind(SeqList* psl, SLDataType x);
// 顺序表在pos位置插入x
void SeqListInsert(SeqList* psl, size_t pos, SLDataType x);
// 顺序表删除pos位置的值
void SeqListErase(SeqList* psl, size_t pos);
// 顺序表销毁
void SeqListDestory(SeqList* psl);
// 顺序表打印
void SeqListPrint(SeqList* psl)

接下来我们来一个一个实现吧。

 2.2-1 动态顺序表实现思路

    我们需要实现顺序表的增删查改等功能,包含十几个方法,为了避免代码混乱等问题,我们将顺序表分成三个文件来实现(1)test.c,这个文件负责我们实现接口之后的测试,(2)SeqList.h,这个文件负责包含所有头文件和放置所有的函数声明,如果另外两个文件要使用这些头文件只需要包含这个文件就可以了,(3)SeqList.h,这个文件负责实现所有方法(函数)的功能,我们顺序表的大部分代码也是在这个文件。

2.2-2 动态顺序表的初始化

     有了思路之后我们就来实现我们的代码。首先我们创建三个文件:

在SeqList文件中包含我们要用到的头文件,输入输出需要用到stdio.h,开辟内存的函数需用到stdlib.h,我们还会用到断言(assert.h),为了避免多次包含头文件以免不必要的内存浪费,我们还会用到#pragma once 这段代码:

#pragma once
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>

接下来我们创建一个顺序表,我们用一个结构体来表示这个顺序表并用typedef将它更名为SL:

typedef int SLDataType;
typedef struct SeqList
{SLDataType* arr;int size;//有效数据int capacity;//空间大小}SL;

那么存储数据的类型为什么也要改名呢?因为我们将来如果使用顺序表存储数据时,我们并不知道我们存何种类型的数据,如果我们存储的数据是int,而要将它们全部换成字符类型,此时恰好我们已经写了100000行代码,我们要修改的化会变得相当困难,所以我们将数据类型改名是为了方便以后我们要存储不同类型数据时可以很方便的更换类型。

我们来实现第一个方法——初始化,在开始时我们将它们都初始化为0:

void SeqInit(SL* ps)
{ps->arr = NULL;ps->size = ps->capacity = 0;
}//初始化
 2.2-3动态顺序表的插入

    我们使用顺序表最主要的功能就是存储数据,而在一开始顺序表是没有数据的,所以我们先实现插入功能,插入分为:尾插,头插,从中间插入。尾插就是在最后一个有效数据后插入我们要插入的数据:

例如这个顺序表有三个有效数据,那么我们的尾插就是将它放在最后一个有效数据(3)的后面,如果我们将数字4用尾插的方式插入顺序表,那么就是这样:

头插则与尾插刚好相反,它是将要插入的数据放在有效数据的最前面,而使其他数据整体往后移一位,假设我们要用头插插入数字0:

使用中间插入我们可以指定插入的位置,如果我们要将数字6插入到3的位置,我们只需要将这个位置后的所有有效数据都往后挪一位:

接下来我们用代码实现。

检查空间

       使用插入前,我们需要为顺序表开辟一块空间,我们在空间上会遇到两个问题:如果我们是第一次进来,所有数据都为0,那么我们要第一次开辟内存;如果我们要存入数据时,内存不足,则需要新开辟内存。这两种情况都有一个共同点——有效数据与空间大小相等,所以只要有序数据和空间大小相等时我们就增加1倍空间,在进入函数时,我们先判断这个指针是不是为空,如果我们向空指针存入数据,则一点会出错,代码实现:

void SeqCheckcapa(SL* ps)//检查内存够不够,不够则增加
{assert(ps);if (ps->capacity == ps->size){int Newcapecity = ps->capacity == 0 ? 4 : 2 * ps->capacity * sizeof(SLDataType);SLDataType* tem = (SLDataType*)realloc(ps->arr, Newcapecity * 2 *sizeof(SLDataType));if (tem != NULL){ps->arr = tem;}}
}
 尾插

  我们使用尾插前先判断我们的空间够不够,传入的指针是否为空。那么我们如何插入呢?我们顺序表中的有效数据是size个,而最后一个有效数据的下标是size-1,我们只需要在下标为size的位置插入数据,然后size加1,就完成了尾插的操作:

void SeqPushBack(SL* ps, SLDataType x)
{assert(ps);SeqCheckcapa(ps);ps->arr[ps->size++] = x;}//尾插

画图演示:

头插 

  头插前面做的事和尾插一样,先判断指针是不是为空,再判断空间够不够。然后将所有数据往后移一位,最后在下标为0的位置插入数据,size加1:

void SeqPushFront(SL* ps, SLDataType x)
{assert(ps);SeqCheckcapa(ps);int i = 0;for (i = ps->size; i > 0; i--){ps->arr[i] = ps->arr[i - 1];} ps->arr[0] = x;++ps->size;
}//头插
中间插入 

先判断指针是否为空和判断空间够不够。因为中间插入是指定位置进行插入,所以我们只能在已经有的数据中间插入,我们指定的数字不能小于0,也不能大于size。当我们指定了一个有效数字pos下标,我们将这个位置及它后面的所有数据往后挪一位,此时这个位置就空出来了,我们也就可以插入我们想插入的数字,插入之后,我们让size加1:

void SLInsert(SL* ps, int pos, SLDataType x)
{assert(ps);assert(pos >= 0 && pos <= ps->size);SeqCheckcapa(ps);int i = 0;for (i = ps->size ; i>pos; i--){ps->arr[i] = ps->arr[i - 1];}ps->arr[pos] = x;++ps->size;}//指定下标前插入数据

2.2-4 动态顺序表的删除 

删除同样分为尾删,头删,中间删除,这部分内容比插入相对简单一点。

尾删

 我们先判断指针是否为空,再判断有效数据的情况,如果有效数据为0,我们就不能删除数据。而删除数据,只需要让size往前挪动一位,我们打印时不会打印这个数据,而插入数据时会将这个数据覆盖:

void SeqPopBack(SL* ps)
{assert(ps);assert(ps->size >= 0);ps->size--;
}//尾删
头删 

与尾删一样,先判断指针是否为空,再判断数据情况。头删操作只需将第二位及后面的所以数据往前移动一位,将第一位数据覆盖,最后让size减1就可以了:

代码实现:

void SeqPopFront(SL* ps)
{assert(ps);assert(ps->size >= 0);int i = 0;for (i = 0; i <ps->size-1 ; i++){ps->arr[i] = ps->arr[i + 1];}ps->size--;}//头删
中间删除 

  先判断指针是否为空,再判断有效数据的情况。因为中间删除是指定位置删除,那么这个制定的数字肯定不能小于0,也不能大于等于size,而删除操作与头删相似,我们指定好数字后,只需要将它后面的所有有效数据往前挪动一位将它覆盖然后让size减1就可以了:

void SLErase(SL* ps, int pos)
{assert(ps);assert(pos >= 0 && pos < ps->size);int i = 0;for (i = pos; i<ps->size-1; i++){ps->arr[i] = ps->arr[i + 1];}ps->size--;
}//指定下标删除

2.2. 5 动态顺序表查找与打印、销毁

查找

查找数据我们先判断指针是否为空。使用循环判断顺序表中是否有我们要查找的数据,如果找到了,则返回它的下标,如果找不到,则返回-1:

int SLFind(SL* ps, SLDataType x)
{assert(ps);int i = 0;for (i = 0; i < ps->size; i++){if (ps->arr[i] == x){return i;}}return -1;
}//查找数据

我们使用一个整型来接收,如果大于0,说明找到了,并打印它的下标,如果小于0,则表示顺序表中没有这个数据:

int find = SLFind(&sl, 4);
if (find < 0)
{printf("没有找到!\n");
}
else
{printf("找到了,下标是%d\n", find);
}
打印 

打印顺序表中的数据要先判断指针是否为空。接着使用循环将它的内容打印出来:

void SeqPrint(SL* ps)
{assert(ps);int i = 0;for (i = 0; i < ps->size; i++){printf("%d ", ps->arr[i]);}printf("\n");
}//打印
销毁 

 当使用完这块动态开辟出来的空间,不要忘了释放,以免造成内存泄漏和出现野指针的情况:

void SeqDestroy(SL* ps)
{assert(ps);free(ps->arr);if (ps->arr != NULL);{ps->arr = NULL;}ps->capacity = ps->size = 0;
}
//销毁

至此所有方法就实现完成了。 

 2.2 6 测试动态顺序表

  我们来测试一下其中一些方法:

void test2()
{SL sl;SeqInit(&sl);//插入1 2 3 4SeqPushBack(&sl, 1);SeqPushBack(&sl, 2);SeqPushBack(&sl, 3);SeqPushBack(&sl, 4);SeqPrint(&sl);//插入99 99SLInsert(&sl, 0, 99);SLInsert(&sl, 3, 88);SLInsert(&sl, sl.size, 10000);SeqPrint(&sl);//删除SLErase(&sl,2);SeqPrint(&sl);SLErase(&sl, 5);SeqPrint(&sl);//查找int find = SLFind(&sl, 4);if (find < 0){printf("没有找到!\n");}else{printf("找到了,下标是%d\n", find);}//释放空间SeqDestroy(&sl);
}

来看运行结果:

可以看到我们实现的方法都没有问题,我将原码放在下面,感兴趣的小伙伴可以试试哦。

SeqList.h :

#pragma once
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>typedef int SLDataType;
typedef struct SeqList
{SLDataType* arr;int size;//有效数据int capacity;//空间大小}SL;void SeqInit(SL* ps);//初始化void SeqDestroy(SL* ps);//销毁void SeqPushBack(SL* ps, SLDataType x);//尾插void SeqPushFront(SL* ps, SLDataType x);//头插void SeqPopBack(SL* ps);//尾删void SeqPopBack(SL* ps);//头删void SeqPrint(SL* ps);//打印void SLErase(SL* ps, int pos);//指定删除int SLFind(SL* ps, SLDataType x);//查找数据//指定下标前插入数据
void SLInsert(SL* ps,int pop, SLDataType x);

SeqList.c :

#define _CRT_SECURE_NO_WARNINGS 1
#include"SeqList.h"void SeqInit(SL* ps)
{ps->arr = NULL;ps->size = ps->capacity = 0;
}//初始化void SeqCheckcapa(SL* ps)//检查内存够不够,不够则增加
{assert(ps);if (ps->capacity == ps->size){int Newcapecity = ps->capacity == 0 ? 4 : 2 * ps->capacity * sizeof(SLDataType);SLDataType* tem = (SLDataType*)realloc(ps->arr, Newcapecity * 2 *sizeof(SLDataType));if (tem != NULL){ps->arr = tem;}}
}void SeqPushBack(SL* ps, SLDataType x)
{assert(ps);SeqCheckcapa(ps);ps->arr[ps->size++] = x;}//尾插void SeqPushFront(SL* ps, SLDataType x)
{assert(ps);SeqCheckcapa(ps);int i = 0;for (i = ps->size; i > 0; i--){ps->arr[i] = ps->arr[i - 1];} ps->arr[0] = x;++ps->size;
}//头插void SeqPopBack(SL* ps)
{assert(ps);assert(ps->size >= 0);ps->size--;
}//尾删void SeqPopFront(SL* ps)
{assert(ps);assert(ps->size >= 0);int i = 0;for (i = 0; i <ps->size-1 ; i++){ps->arr[i] = ps->arr[i + 1];}ps->size--;}//头删void SLInsert(SL* ps, int pos, SLDataType x)
{assert(ps);assert(pos >= 0 && pos <= ps->size);SeqCheckcapa(ps);int i = 0;for (i = ps->size ; i>pos; i--){ps->arr[i] = ps->arr[i - 1];}ps->arr[pos] = x;++ps->size;}//指定下标前插入数据void SLErase(SL* ps, int pos)
{assert(ps);assert(pos >= 0 && pos < ps->size);int i = 0;for (i = pos; i<ps->size-1; i++){ps->arr[i] = ps->arr[i + 1];}ps->size--;
}//指定下标删除int SLFind(SL* ps, SLDataType x)
{assert(ps);int i = 0;for (i = 0; i < ps->size; i++){if (ps->arr[i] == x){return i;}}return -1;
}//查找数据
void SeqPrint(SL* ps)
{assert(ps);int i = 0;for (i = 0; i < ps->size; i++){printf("%d ", ps->arr[i]);}printf("\n");
}//打印void SeqDestroy(SL* ps)
{assert(ps);free(ps->arr);if (ps->arr != NULL);{ps->arr = NULL;}ps->capacity = ps->size = 0;
}
//销毁

test.c :

#define _CRT_SECURE_NO_WARNINGS 1
#include"SeqList.h"
//void SLPushBack(SL* ps, SLDatatype x)
//{
//	assert(ps);
//
//	if (ps->size == ps->capacity)
//	{
//		int Newcapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;
//
//		SLDatatype* tem=(SLDatatype*)realloc(ps->arr,2* Newcapacity*sizeof(SLDatatype))
//			if (tem == NULL)
//			{
//				perror("realloc");
//				exit(1);
//			}
//
//		ps->arr = tem;
//		ps->capacity = Newcapacity;
//	}
//	ps->arr[size++] = x;
//
//}
//
//
//
//
//void SLPushBack(SL* ps, SLDataType x)
//{
//	//1.判断指针是否为空,为空则出错
//	assert(ps);
//
//	//2.判断空间够不够,不够则申请空间
//	if (ps->capecity == ps->size)
//	{
//		//如果capecity为0,我们就要第一次开辟出4个SLDataType类型的空间
//		SLDataType NewCapecity = ps->capecity == 0 ? 4 : 2 * ps->capecity;
//		//开辟空间,如果下次空间不够,则下次开辟此次2倍的空间
//		SLDataType* tem = (SLDataType*)realloc(ps->arr, NewCapecity * 2 * sizeof(SLDataType));
//		if (tem == NULL)
//		{
//			perror("realloc");
//			exit(1);
//		}
//		//走到这里说明tem不为空,将新开辟好的内存给arr
//		ps->arr = tem;
//		ps->capecity = NewCapecity;
//	}
//	ps->arr[ps->size++] = x;
//	//3.进行尾插操作
//}
void test1()
{SL sl;SeqInit(&sl);SeqPushBack(&sl, 1);SeqPushBack(&sl, 2);SeqPushBack(&sl, 3);SeqPushBack(&sl, 4);SeqPrint(&sl);SeqPushFront(&sl, 6);SeqPrint(&sl);SeqPopBack(&sl);SeqPrint(&sl);SeqPopFront(&sl);SeqPopFront(&sl); SeqPopFront(&sl); SeqPrint(&sl);SeqDestroy(&sl);
}
void test2()
{SL sl;SeqInit(&sl);//插入1 2 3 4SeqPushBack(&sl, 1);SeqPushBack(&sl, 2);SeqPushBack(&sl, 3);SeqPushBack(&sl, 4);SeqPrint(&sl);//插入99 99SLInsert(&sl, 0, 99);SLInsert(&sl, 3, 88);SLInsert(&sl, sl.size, 10000);SeqPrint(&sl);//删除SLErase(&sl,2);SeqPrint(&sl);SLErase(&sl, 5);SeqPrint(&sl);//查找int find = SLFind(&sl, 4);if (find < 0){printf("没有找到!\n");}else{printf("找到了,下标是%d\n", find);}//释放空间SeqDestroy(&sl);
}
int main()
{test2();//test1();return 0;
}

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

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

相关文章

使用fvm切换flutter版本

切换flutter版本 下载fvm 1、dart pub global activate fvm dart下载fvm 2、warning中获取下载本地的地址 3、添加用户变量path&#xff1a; 下载地址 终端查看fvm版本 fvm --version 4、指定fvm文件缓存地址 fvm config --cache-path C:\src\fvm&#xff08;自定义地址&…

使用Zed 实现测距

目录 1. 导入相关库 2. 相机初始化设置 3. 获取中心点深度数据 4. 计算中心点深度值 5. 完整代码 此代码基于官方代码基础上进行改写,主要是获取zed相机深度画面中心点的深度值,为yolo测距打基础。 Zed相机是由Stereolabs公司开发的一种先进的立体视觉相机。这种相机专…

LinkFinder使用记录

在Windows上使用linkfinder报出如下错误&#xff1a; 解决办法&#xff1a; 进入linkfinder.py中将如下代码注释掉即可~ print("URL to access output: file://%s" % os.path.abspath(args.output))

使用Leaflet库创建交互式地图:技术解析与实践

一&#xff1a;引言 在现代Web开发中&#xff0c;地图可视化已成为许多项目不可或缺的一部分。Leaflet是一个开源的JavaScript库&#xff0c;用于在Web页面上创建交互式地图。它简单易用、轻量级且高度可定制&#xff0c;使得开发者能够快速地创建出具有丰富功能的地图应用。本…

618有什么值得推荐?2024数码产品推荐,轻松拿捏选购!

随着618购物节即将来临&#xff0c;你是否已被琳琅满目的商品所吸引&#xff0c;难以抉择&#xff1f;团团特意为你筛选出一系列经过亲身试验的优质好物&#xff0c;旨在帮助你在这场购物盛宴中迅速锁定心仪之选。这些推荐不仅走在时尚的前沿&#xff0c;更能满足你日常生活的各…

java:spring使用【XXXPostProcessor】添加bean定义,修改bean定义、代理bean

# 项目代码资源&#xff1a; 可能还在审核中&#xff0c;请等待。。。 https://download.csdn.net/download/chenhz2284/89433361 # 项目代码 【pom.xml】 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-start…

GaussDB技术解读——GaussDB架构介绍(三)

目录 9 智能关键技术方案 智能关键技术一&#xff1a;自治运维系统 智能关键技术二&#xff1a;库内AI引擎 智能关键技术三&#xff1a;智能优化器 10 驱动接口关键技术方案 GaussDB架构介绍&#xff08;二&#xff09;从数据持久化存取层(DataNode)关键技术方案、全局事…

list容器的基本使用

目录 前言一&#xff0c;list的介绍二&#xff0c;list的基本使用2.1 list的构造2.2 list迭代器的使用2.3 list的头插&#xff0c;头删&#xff0c;尾插和尾删2.4 list的插入和删除2.5 list 的 resize/swap/clear 前言 list中的接口比较多&#xff0c;与string和vector类似&am…

全面解说Facebook代投菲律宾真金游戏pwa广告全流程

全面解说Facebook代投菲律宾真金游戏pwa广告全流程 随着数字营销的不断发展&#xff0c;社交媒体平台如Facebook已成为广告主们争相投放的热门渠道。对于希望拓展菲律宾市场的真金游戏企业来说&#xff0c;了解并掌握在Facebook上投放广告的具体流程显得尤为重要。本文将详细介…

SQL SERVER触发器记录指定的几笔资料更新记录

1.目的 为了记录数据库表中资料数据动态的变更&#xff0c;实时动态且方便调整记录的范围。 2.分析 需求:记录UPDATE 修改的记录 if exists(select 1 from inserted) and exists(select 1 from deleted) &#xff1a;修改if (exists (select 1 from inserted) and n…

[Nacos]No spring.config.import property has been defined

在学习 Spring Cloud Alibaba &#xff0c;Nacos组件&#xff0c;创建一个cloudalibaba-config-nacos-client&#xff0c;加载多配置集时遇到问题 配置了 bootstrap.yml 后启动项目报错&#xff1a; 是因为在springcloud 2020.0.2版本中把bootstrap的相关依赖从spring-cloud-s…

电脑文件msvcr120.dll丢失怎样修复?具体的msvcr120.dll修复方法分享

电脑文件msvcr120.dll丢失是一种比较常见的现象&#xff0c;只要是经常使用电脑的人&#xff0c;那么遇到msvcr120.dll丢失的次数就越多&#xff0c;今天主要来给大家聊一下msvcr120.dll丢失的各种解决方法。 一.电脑文件msvcr120.dll msvcr120.dl是由Microsoft提供的关键系统…

Qt飞机大战小游戏

Gitee地址 &#xff1a;plane-game: 基于Qt的飞机大战小游戏 GitHub地址&#xff1a; https://github.com/a-mo-xi-wei/plane-game

微信鸿蒙版本来了 我不允许你不会

前言: 各位同学大家好, 好久没有更新鸿蒙文章了 现在更新一个鸿蒙版本高仿微信版本 那么废话不多说 我们正式开始 作者:徐庆 团队:坚果派 公众号:“大前端之旅” 润开鸿生态技术专家,华为HDE,CSDN博客专家,CSDN超级个体,CSDN特邀嘉宾,InfoQ签约作者,OpenHarmony布…

2024牛客网高频精选Java面试八股文整理(附答案)

Java 面试 Java 作为编程语言中的 NO.1,选择入行做 IT 做编程开发的人&#xff0c;基本都把它作为首选语言,进大厂拿高薪也是大多数小伙伴们的梦想。以前 Java 岗位人才的空缺&#xff0c;而需求量又大&#xff0c;所以这种人才供不应求的现状&#xff0c;就是 Java 工程师的薪…

【CH32V305FBP6】USBD HS 描述符修改

文章目录 前言设备描述符配置描述符配置描述符CDC 描述符接口关联描述符接口描述符功能描述符端点描述符接口描述符端点描述符 HID 描述符接口描述符 练习&#xff1a;新增一个 HID 设备 前言 USB HS 复合设备&#xff0c;CDCHID 功能&#xff1a;串口、DAP、CAN-HID、RS485 …

健身小程序:智能化助力个人健身旅程

一、智能化功能的核心 健身小程序的智能化功能主要体现在以下几个方面&#xff1a; 智能健身计划推荐&#xff1a;小程序内置了先进的算法&#xff0c;能够根据用户的身体状况、健身目标和时间安排&#xff0c;智能推荐个性化的健身计划。这些计划不仅科学合理&#xff0c;而且…

零基础入门学用Arduino 第二部分(二)

重要的内容写在前面&#xff1a; 该系列是以up主太极创客的零基础入门学用Arduino教程为基础制作的学习笔记。个人把这个教程学完之后&#xff0c;整体感觉是很好的&#xff0c;如果有条件的可以先学习一些相关课程&#xff0c;学起来会更加轻松&#xff0c;相关课程有数字电路…

Pytorch环境配置的方法

Pytorch虚拟环境配置全流程 以安装pytorch1.9.1为例 1. 创建虚拟环境 安装Anaconda3&#xff0c;打开 PowerShell 创建虚拟环境并进入&#xff1a; conda create -n torch1.9.1 python3.8 conda activate torch1.9.1 conda create -n torch1.9.1 python3.8 conda activate to…

Flowable-决策表设计器

✨✨✨ 最好用的Flowable决策表设计器 ✨✨✨ 最好用的Flowable流程设计器 本文中内容和案例出自贺波老师的书《深入Activiti流程引擎&#xff1a;核心原理与高阶实战》&#xff0c;书中的介绍更全面、详细&#xff0c;推荐给大家。 深入Activiti流程引擎