数据结构:打造高效的通讯录项目

news2025/5/25 13:07:09

 ✨✨小新课堂开课了,欢迎欢迎~✨✨

🎈🎈养成好习惯,先赞后看哦~🎈🎈

所属专栏:http://t.csdnimg.cn/oHJAK(数据结构与算法)

小新的主页:编程版小新-CSDN博客

今天就和小新一起来实现超级有意思的通讯录项目吧。通讯录其实就是顺序表,对通讯录的实现其实就是对顺序表的实现,只是我们又给顺序表起了一个新的名字叫通讯录。这一点一定要记住,不然在下面实现代码的时候就很容易晕头转向。

在上一篇文章中我们实现的顺序表中存放的是整型数据,现在我们要实现通讯录,根本不同就是存放的数据不同,要实现通讯录,我们存放的是结构体,结构体里包含了联系人的信息。

顺序表(通讯录)的实现是基于结构体,指针,动态内存开辟的,如果不是很理解的话,可以先收藏。http://t.csdnimg.cn/Oytke (这个是C语言的专栏,有需要的话可以看一下)

1.顺序表 

我们先看顺序表的实现:

SeqList.c:

#include"SeqList.h"
//顺序表的初始化
void SLInit(SL* ps)//传址调用
{
	ps->arr = NULL;
	ps->size = ps->capacity = 0;
}
//顺序表的销毁
void SLDestroy(SL* ps)
{
	if (ps->arr != NULL)//ps->arr
	{
		free(ps->arr);
	}
	ps->arr = NULL;//避免访问野指针
	ps->size = ps->capacity = 0;
}

//检查是否用足够的空间
void SLCheck(SL* ps)
{
	if (ps->size == ps->capacity)//空间不够
	{
		//申请空间
		//三目操作符
		int newcapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;//少了等号。一个是赋值
		SLDataType* tmp = (SLDataType*)realloc(ps->arr, newcapacity * sizeof(SLDataType));//需要申请多大的空间
		if (tmp == NULL)
		{
			perror("realloc fail");
			return;
		}
		//申请成功
		ps->arr = tmp;
		ps->capacity = newcapacity;
	}

}

//打印顺序表
void SLPrint(SL ps)
{
	for (int i = 0; i < ps.size; i++)
	{
		printf("%d ", ps.arr[i]);
	}
	printf("\n");
}

//顺序表的尾插
void SLPushBack(SL* ps, SLDataType x)
{
	assert(ps);
	//插入之前要检查是否有空间
	SLCheck(ps);
	//插入
	ps->arr[ps->size++] = x;//细节之后置++
}


//头插
void SLPushFront(SL* ps, SLDataType x)
{
	assert(ps);
	//插入之前要检查是否有足够的空间
	SLCheck(ps);
	//先让顺序表中已有的数据整体往后移动一位
	for (int i = ps->size; i > 0; i--)
	{
		ps->arr[i] = ps->arr[i - 1];
	}
	ps->arr[0] = x;
	ps->size++;//不要忘记++
}

//在指定位置之前插入数据
void SLInsert(SL* ps, int pos, SLDataType x)
{
	assert(ps);
	assert(pos >= 0 && pos <= ps->size);
	//插入之前要检查空间够不够
	SLCheck(ps);
	//先让pos及其之后的数据整体往后挪动一位
	for (int i = ps->size; i > pos; i--)
	{
		ps->arr[i] = ps->arr[i - 1];//ps->arr[pos+1]=ps->arr[pos]
	}
	ps->arr[pos] = x;
	ps->size++;
}

//删除指定位置的数据
void SLErase(SL* ps, int pos)
{
	assert(ps);
	assert(pos >= 0 && pos < ps->size);
	//让pos之后的数据整体往前挪动一位
	for (int i = pos; i< ps->size - 1; i++)
	{
		ps->arr[i] = ps->arr[i + 1];
	}
	ps->size--;

}
//顺序表的尾删
void SLPopBack(SL* ps)
{
	assert(ps);
	assert(ps->size);//顺序表不能为空
	--ps->size;
}

//顺序表的头删
void SLPopFront(SL* ps)
{
	assert(ps);
	assert(ps->size);
	//整体往前挪动一位
	for (int i = 0; i < ps->size - 1; i++)
	{
		ps->arr[i] = ps->arr[i + 1];
	}
	ps->size--;
}


//修改指定位置的数据
void SeqListModify(SL* ps, int pos, SLDataType x)
{
	assert(ps);  //断言
	assert(ps->size > 0);  //顺序表不能为空
	assert(pos >= 0 && pos < ps->size);  //检查pos下标的合法性
	ps->arr[pos] = x;  //修改pos下标处对应的数据
}


//查找指定数据
int SLFind(SL* ps, SLDataType x)
{
	assert(ps);
	for (int i = 0; i < ps->size; i++)
	{
		if (ps->arr[i] == x)
		{
			//找到了
			return i;//返回下标
		}
	}
	//没有找到
	return -1;

}

SeqList.h:

#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
//定义顺序表

//静态顺序表
//#define N 100
//
//struct SeqList
//{
//	int arr[N];
//	int size;//有效数据个数
//};

//动态顺序表
typedef int SLDataType;
typedef struct SeqList
{
	SLDataType* arr;
	int size;//有效数据个数
	int capacity;//空间大小
}SL;

//顺序表的初始化
void SLInit(SL* ps);

//顺序表的销毁
void SLDestroy(SL* ps);

//尾部插入
void SLPushBack(SL* ps, SLDataType x);

//尾部删除
void SLPopBack(SL* ps);

//头部插入
void SLPushFront(SL* ps, SLDataType x);

//头部删除
void SLPopFront(SL* ps);

//指定位置插入
void SLInsert(SL* ps, int pos, SLDataType x);

//指定位置删除
void SLErase(SL* ps, int pos);

//打印顺序表
void SLPrint(SL ps);

//查找数据
int SLFind(SL* ps, SLDataType x);

//修改指定位置的数据
void SeqListModify(SL* ps, int pos, SLDataType x);

如果不能理解的话: 数据结构:去发现顺序表的魅力所在-CSDN博客

既然通讯录就是顺序表,我们要实现通讯录就是基于在顺序表的基础上去扩展的。

2.通讯录的功能

1.通讯录的声明

2.通讯录的初始化

3.添加联系人

4.删除联系人

5.查找联系人

6.修改联系人

7.展示通讯录

8.销毁通讯录

3.通讯录的功能实现

一定要理解对通讯录的实现就是对顺序表的实现,在顺序表中实现的功能,下面我们会直接调用使用。

3.1通讯录的声明

#pragma once//防止重复引入产生问题
#define NAME_MAX 20
#define GENDER_MAX 10
#define TEL_MAX 20
#define ADDR_MAX 100

//定义联系人数据 结构
//姓名 性别  年龄  电话  地址
 typedef struct personInfo//方便书写,给结构体起一个简单的名字peoInfo
{
	char name[NAME_MAX];
	char gender[GENDER_MAX];
	int age;
	char tel[TEL_MAX];
	char addr[ADDR_MAX];
}peoInfo;

3.2通讯录的初始化

对通讯录的实现其实就是就是对顺序表的实现
通讯录就是顺序表,只是又给顺序表起了一个新的名字叫通讯录

实现通讯录要用到顺序表的方法,下面就给顺序表起一个新的名字叫通讯录Contact

typedef struct SeqList Contact;
//通讯录的初始化
void ContactInit(Contact* con)
{
	//对通讯录的初始化其实就是对顺序表的初始化
	//顺序表的初始化前面已经实现好了,直接调用就好了
	 SLInit(con);
}

3.3添加联系人数据

//通讯录添加数据
void ContactAdd(Contact* con)
{
	//获取用户的内容:姓名+性别+年龄+电话+住址
	peoInfo info;
	printf("请输入要添加的联系人的姓名\n");
	scanf("%s", info.name);

	printf("请输入要添加的联系人的性别\n");
	scanf("%s", info.gender);

	printf("请输入要添加的联系人的年龄\n");
	scanf("%d", &info.age);

	printf("请输入要添加的联系人的电话\n");
	scanf("%s", info.tel);

	printf("请输入要添加的联系人的住址\n");
	scanf("%s", info.addr);
	
	//往通讯录里添加用户即联系人的信息
	//这里采用尾插
	 SLPushBack(con, info);
}

3.4查找联系人 

//通讯录的查找
void ContactFind(Contact* con)
{
	char name[NAME_MAX];
	printf("请输入要查找的联系人姓名\n");
	scanf("%s", name);

	int find = FindName(con,name);
	if (find < 0)
	{
		printf("没有该联系人\n");
		return;
	}
	else
	{
		printf("%s %s %s %s %s\n", "姓名", "性别", "年龄", "电话", "住址");
		printf("%3s %3s %3d %3s %3s\n",
			con->arr[find].name,
			con->arr[find].gender,
			con->arr[find].age,
			con->arr[find].tel,
			con->arr[find].addr
		);//这里根据需要修改格式
	}
}

3.5删除联系人数据

//查找联系人姓名
int FindName(Contact* con ,char name[])
{
	
	for (int i = 0; i < con->size; i++)
	{
		if (0 == strcmp(con->arr[i].name, name))
		{
			//找到了
			return i;
		}
	}
	//没有找到
	return -1;
}
//通讯录删除数据
void ContactDel(Contact* con)
{
	//要删除的数据必须存在
	//查找要删除的联系人
	//这里我们按名字进行查找
	char name[NAME_MAX];
	printf("请输入要删除的联系人姓名\n");
	scanf("%s", name);
	int find = FindName(con, name);
	if (find < 0)
	{
		printf("要删除的联系人信息不存在\n");
	}
	//要删除的联系人信息存在
	SLErase(con, find);
	printf("删除成功\n");

}

3.6修改联系人信息

//修改联系人信息
void ContactModity(Contact* con)
{
	//要修改的联系人数据存在
	printf("请输入要修改的联系人姓名\n");
	char name[NAME_MAX];
	scanf("%s", name);
	int find = FindName(con, name);
	if (find < 0)
	{
		printf("要修改的联系人信息不存在\n");
		return;
	}
	//直接修改
	printf("请输入新的姓名:\n");
	scanf("%s", con->arr[find].name);

	printf("请输入新的性别:\n");
	scanf("%s", con->arr[find].gender);

	printf("请输入新的年龄:\n");
	scanf("%d",&con->arr[find].age);

	printf("请输入新的电话:\n");
	scanf("%s", con->arr[find].tel);

	printf("请输入新的住址:\n");
	scanf("%s", con->arr[find].addr);

	printf("修改成功\n");
}

3.7展示通讯录

//展示通讯录
void ContactShow(Contact* con)
{
	//打印表头
	printf("%s %s %s %s %s\n", "姓名", "性别", "年龄", "电话", "住址");
	//遍历通讯录,打印通讯录的联系人信息
	for (int i = 0; i < con->size; i++)
	{
		printf("%3s %3s %3d %3s %3s\n",
			con->arr[i].name,
			con->arr[i].gender,
			con->arr[i].age,
			con->arr[i].tel,
			con->arr[i].addr
			);//这里根据需要修改位置,让打印的更加美观
	}

}

3.9销毁通讯录

//通讯录的销毁
void ContactDestroy(Contact* con)
{
	 SLDestroy(con);
}

4.整体代码

Contact.h:

#pragma once//防止重复引入问题
#define NAME_MAX 20
#define GENDER_MAX 10
#define TEL_MAX 20
#define ADDR_MAX 100

//定义联系人数据 结构
//姓名 性别  年龄  电话  地址
 typedef struct personInfo
{
	char name[NAME_MAX];
	char gender[GENDER_MAX];
	int age;
	char tel[TEL_MAX];
	char addr[ADDR_MAX];
}peoInfo;


//对通讯录的实现其实就是就是对顺序表的实现
//通讯录就是顺序表,只是又给顺序表起了一个新的名字叫通讯录

//实现通讯录要用到顺序表的方法,下面就给顺序表起一个新的名字叫通讯录
typedef struct SeqList Contact;

//通讯录的相关方法

//通讯录的初始化
void ContactInit(Contact* con);

//通讯录的销毁
//void ContactDestroy(Contact* con);

//通讯录添加数据
void ContactAdd(Contact* con);

//通讯录删除数据
void ContactDel(Contact* con);

//通讯录的修改
void ContactModity(Contact* con);

//展现通讯录
void ContactShow(Contact* con);

//查找通讯录
void ContactFind(Contact* con);

Contact.c:

#include"SeqList.h"
#include"Contact.h"
//通讯录的初始化
void ContactInit(Contact* con)
{
	//对通讯录的初始化其实就是对顺序表的初始化
	//顺序表的初始化前面已经实现好了,直接调用就好了
	 SLInit(con);
}

//通讯录的销毁
void ContactDestroy(Contact* con)
{
	 SLDestroy(con);
}
//通讯录添加数据
void ContactAdd(Contact* con)
{
	//获取用户的内容:姓名+性别+年龄+电话+住址
	peoInfo info;
	printf("请输入要添加的联系人的姓名\n");
	scanf("%s", info.name);

	printf("请输入要添加的联系人的性别\n");
	scanf("%s", info.gender);

	printf("请输入要添加的联系人的年龄\n");
	scanf("%d", &info.age);

	printf("请输入要添加的联系人的电话\n");
	scanf("%s", info.tel);

	printf("请输入要添加的联系人的住址\n");
	scanf("%s", info.addr);
	
	//往通讯录里添加用户即联系人的信息
	//这里采用尾插
	 SLPushBack(con, info);
}

//查找联系人
int FindName(Contact* con ,char name[])
{
	
	for (int i = 0; i < con->size; i++)
	{
		if (0 == strcmp(con->arr[i].name, name))
		{
			//找到了
			return i;
		}
	}
	//没有找到
	return -1;
}

//通讯录删除数据
void ContactDel(Contact* con)
{
	//要删除的数据必须存在
	//查找要删除的联系人
	//这里按名字进行查找
	char name[NAME_MAX];
	printf("请输入要删除的联系人姓名\n");
	scanf("%s", name);
	int find = FindName(con, name);
	if (find < 0)
	{
		printf("要删除的联系人信息不存在\n");
	}
	//要删除的联系人信息存在
	SLErase(con, find);
	printf("删除成功\n");

}
//修改联系人信息
void ContactModity(Contact* con)
{
	//要修改的联系人数据存在
	printf("请输入要修改的联系人姓名\n");
	char name[NAME_MAX];
	scanf("%s", name);
	int find = FindName(con, name);
	if (find < 0)
	{
		printf("要修改的联系人信息不存在\n");
		return;
	}
	//直接修改
	printf("请输入新的姓名:\n");
	scanf("%s", con->arr[find].name);

	printf("请输入新的性别:\n");
	scanf("%s", con->arr[find].gender);

	printf("请输入新的年龄:\n");
	scanf("%d",&con->arr[find].age);//scanf传入咋用的,好好想想,看下之前的例子,这个得好好记住了,再检查下

	printf("请输入新的电话:\n");
	scanf("%s", con->arr[find].tel);

	printf("请输入新的住址:\n");
	scanf("%s", con->arr[find].addr);

	printf("修改成功\n");
}

//展示通讯录
void ContactShow(Contact* con)
{
	//打印表头
	printf("%s %s %s %s %s\n", "姓名", "性别", "年龄", "电话", "住址");
	//遍历通讯录,打印通讯录的联系人信息
	for (int i = 0; i < con->size; i++)
	{
		printf("%3s %3s %3d %3s %3s\n",
			con->arr[i].name,
			con->arr[i].gender,
			con->arr[i].age,
			con->arr[i].tel,
			con->arr[i].addr
			);
	}

}

//通讯录的查找
void ContactFind(Contact* con)
{
	char name[NAME_MAX];
	printf("请输入要查找的联系人姓名\n");
	scanf("%s", name);

	int find = FindName(con,name);
	if (find < 0)
	{
		printf("没有该联系人\n");
		return;
	}
	else
	{
		printf("%s %s %s %s %s\n", "姓名", "性别", "年龄", "电话", "住址");
		printf("%3s %3s %3d %3s %3s\n",
			con->arr[find].name,
			con->arr[find].gender,
			con->arr[find].age,
			con->arr[find].tel,
			con->arr[find].addr
		);
	}
}

SeqList.h:

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<string.h>
#include"Contact.h"
//定义数据结构

//静态数据结构
//#define N 100
//
//struct SeqList
//{
//	int arr[N];
//	int size;//有效数据个数
//};

//动态数据结构
typedef peoInfo SLDataType;
typedef struct SeqList
{
	SLDataType* arr;
	int size;//有效数据个数
	int capacity;//空间大小
}SL;

//顺序表的初始化
void SLInit(SL* ps);

//顺序表的销毁
void SLDestroy(SL* ps);

//尾部插入
void SLPushBack(SL* ps, SLDataType x);

//尾部删除
void SLPopBack(SL* ps);

//头部插入
void SLPushFront(SL* ps, SLDataType x);

//头部删除
void SLPopFront(SL* ps);

//指定位置插入
void SLInsert(SL* ps, int pos, SLDataType x);

//指定位置删除
void SLErase(SL* ps, int pos);

SeqList.c:

#include"SeqList.h"
//顺序表的初始化
void SLInit(SL* ps)//传址调用
{
	ps->arr = NULL;
	ps->size = ps->capacity = 0;
}
//顺序表的销毁
void SLDestroy(SL* ps)
{
	if (ps->arr != NULL)//ps->arr
	{
		free(ps->arr);
	}
	ps->arr = NULL;//避免访问野指针
	ps->size = ps->capacity = 0;
}

//检查是否用足够的空间
void SLCheck(SL* ps)
{
	if (ps->size == ps->capacity)//空间不够
	{
		//申请空间
		//三目操作符
		int newcapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;
		SLDataType* tmp = (SLDataType*)realloc(ps->arr, newcapacity * sizeof(SLDataType));//需要申请多大的空间
		if (tmp == NULL)
		{
			perror("realloc fail");
			return;
		}
		//申请成功
		ps->arr = tmp;
		ps->capacity = newcapacity;
	}

}


//顺序表的尾插
void SLPushBack(SL* ps, SLDataType x)
{
	assert(ps);
	//插入之前要检查是否有空间
	SLCheck(ps);
	//插入
	ps->arr[ps->size++] = x;//细节之后置++
}


//头插
void SLPushFront(SL* ps, SLDataType x)
{
	assert(ps);
	//插入之前要检查是否有足够的空间
	SLCheck(ps);
	//先让顺序表中已有的数据整体往后移动一位
	for (int i = ps->size; i > 0; i--)
	{
		ps->arr[i] = ps->arr[i - 1];
	}
	ps->arr[0] = x;
	ps->size++;//不要忘记++
}

//在指定位置之前插入数据
void SLInsert(SL* ps, int pos, SLDataType x)
{
	assert(ps);
	assert(pos >= 0 && pos <= ps->size);
	//插入之前要检查空间够不够
	SLCheck(ps);
	//先让pos及其之后的数据整体往后挪动一位
	for (int i = ps->size; i > pos; i--)
	{
		ps->arr[i] = ps->arr[i - 1];//ps->arr[pos+1]=ps->arr[pos]
	}
	ps->arr[pos] = x;
	ps->size++;
}

//删除指定位置的数据
void SLErase(SL* ps, int pos)
{
	assert(ps);
	assert(pos >= 0 && pos < ps->size);
	//让pos之后的数据整体往前挪动一位
	for (int i = pos; i< ps->size-1; i++)
	{
		ps->arr[i] = ps->arr[i + 1];
	}
	ps->size--;

}
//顺序表的尾删
void SLPopBack(SL* ps)
{
	assert(ps);
	assert(ps->size);//顺序表不能为空
	--ps->size;
}

//顺序表的头删
void SLPopFront(SL* ps)
{
	assert(ps);
	assert(ps->size);
	//整体往前挪动一位
	for (int i = 0; i < ps->size - 1; i++)
	{
		ps->arr[i] = ps->arr[i + 1];
	}
	ps->size--;
}

text.c:

#include"SeqList.h"
#include"Contact.h"

通讯录的测试方法
//void SLTest01()
//{
//	Contact con;//创建通讯录对象其实实际上就是顺序表对象 等同于SL sl
//	SLInit(&con);
//	ContactAdd(&con);
//	ContactAdd(&con);
//	ContactShow(&con);
//
//
//}//大家在实现通讯录的功能的时候,可以写完一个功能就去测试一个功能,避免堆在一起难找到错误

void menu()
{
	printf("****************通讯录****************\n");
	printf("******1.增加联系人  2.删除联系人******\n");
	printf("******3.修改联系人  4.查找联系人******\n");
	printf("******5.展示联系人  0.  退出   *******\n");
	printf("**************************************\n");
}


int main()
{
	int op = 0;
	Contact con;
	ContactInit(&con);
	do{
		menu();
		printf("请选择菜单:");
		scanf("%d", &op);
		switch (op)
		{
		case 1:
			ContactAdd(&con);
			break;
		case 2:
			ContactDel(&con);
			break;
		case 3:
			ContactModity(&con);
			break;
		case 4:
			ContactFind(&con);
			break;
		case 5:
			ContactShow(&con);
			break;
		case 0:
			printf("退出通讯录...\n");
			break;
		default:
			printf("输出错误,请重新选择你的操作\n");
			break;
		}

	} while (op != 0);
	//SLTest01();
	ContactDestroy(&con);
	return 0;
}

下课了~

下次别忘了来哦

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

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

相关文章

windows应急中的快捷键

windows应急中的快捷键 应急的时候&#xff0c;快捷键很重要&#xff0c;记录一下windows主机排查需要用到的快捷键 windows快捷键 appwiz.cpl 是打开安装面板 程序和功能 控制面板程序和功能 搜索程序和功能 控制而板主页 卸载或更改程序 若要卸酸程序,请从列表中将其…

Python十大常用库:让你的Python编程更上一层楼

Python是一种功能强大的编程语言&#xff0c;拥有众多的第三方库和框架&#xff0c;使得开发者可以更加高效、便捷地进行编程工作。本文将介绍Python中最常用的十大库&#xff0c;这些库在数据科学、机器学习、Web开发等领域有着广泛的应用&#xff0c;可以帮助你更好地提升Pyt…

flask后端+网页前端:基于 socket.io 的双向通信和服务器部署

我想实现的效果是&#xff0c;我的服务器提供两个路由网址&#xff0c;网页A用于拍照、然后录音&#xff0c;把照片和录音传给服务器&#xff0c;服务器发射信号&#xff0c;通知另一个路由的网页B更新&#xff0c;把刚刚传来的照片和录音显示在网页上。 然后网页B用户根据这个…

分享 WebStorm 2024 激活的方案,支持JetBrains全家桶

大家好&#xff0c;欢迎来到金榜探云手&#xff01; WebStorm公司简介 JetBrains 是一家专注于开发工具的软件公司&#xff0c;总部位于捷克。他们以提供强大的集成开发环境&#xff08;IDE&#xff09;而闻名&#xff0c;如 IntelliJ IDEA、PyCharm、和 WebStorm等。这些工具…

K3 BOS插件实现作息时间的选择

要求做一个工时登记表&#xff0c;其中要扣减中午休息时间。公司夏令休息1.5个小时、冬令休息1个小时是不变的&#xff0c;基本思路是根据日期来判断&#xff0c;但在做表单时发现值更新事件中这个日期判断不好写&#xff0c;于是通过写BOS插件来实现这个功能。 首先新建的BOS…

【学习】软件信创测试中,如何做好兼容性适配

在软件信创测试的领域中&#xff0c;兼容性适配是至关重要的一环。如何确保软件在不同的操作系统、硬件设备和软件环境中稳定运行&#xff0c;是每个测试人员需要面对的挑战。本文将从几个方面探讨如何做好兼容性适配&#xff0c;以提高软件的稳定性和用户体验。 首先&#xf…

网页端HTML使用MQTTJs订阅RabbitMQ数据

最近在做一个公司的日志组件时有一个问题难住了我。今天问题终于解决了。由于在解决问题中&#xff0c;在网上也查了很多资料都没有一个完整的实例可以参考。所以本着无私分享的目的记录一下完整的解决过程和实例。 需求&#xff1a;做一个统一日志系统可以查看日志列表和一个可…

轻量化模块整理,即插即用

轻量化模块整理&#xff0c;即插即用&#xff08;持续更新&#xff09; 整理一些轻量化的结构&#xff0c;作为知识储备&#xff0c;可以用到后续的项目和研究中 Mobilenetv3 深度可分离卷积 MobileNetV3 是一个轻量级的深度学习模型&#xff0c;专为移动和边缘设备上的高效…

IntelliJ IDEA 2024 for Mac/Win:引领Java开发新纪元的高效集成环境

在日新月异的软件开发领域&#xff0c;一款高效、智能的集成开发环境&#xff08;IDE&#xff09;无疑是程序员们不可或缺的神兵利器。今天&#xff0c;我要为大家介绍的&#xff0c;正是这样一款集大成之作——IntelliJ IDEA 2024。无论是Mac用户还是Windows用户&#xff0c;只…

Golang | Leetcode Golang题解之第27题移除元素

题目&#xff1a; 题解&#xff1a; func removeElement(nums []int, val int) int {left, right : 0, len(nums)for left < right {if nums[left] val {nums[left] nums[right-1]right--} else {left}}return left }

8个 可以让 Python 加速的 tips

Python 是一种脚本语言&#xff0c;相比 C/C 这样的编译语言&#xff0c;在效率和性能方面存在一些不足。但是&#xff0c;有很多时候&#xff0c;Python 的效率并没有想象中的那么夸张。本文对一些 Python 代码加速运行的技巧进行整理。 0. 代码优化原则 本文会介绍不少的 P…

攻防世界12-baby_web

12-baby_web 题目说想想初始页面是哪个&#xff0c;一般都是index.php&#xff0c;然后如题分析即可。 我们在链接后面拼接上/index.php&#xff0c;返回后发现界面又回到了1.php&#xff0c;有可能是重定向。 我们点击检查-网络&#xff0c;发现没有index的请求&#xff0c;…

番外篇 | YOLOv8改进之在C2f中引入即插即用RepViTBlock模块 | CVPR2024清华RepViT

前言:Hello大家好,我是小哥谈。YOLOv8是一种基于深度学习的实时物体检测算法,其通过将物体检测任务转化为目标框回归问题,并使用卷积神经网络实现高效的特征提取和目标分类。然而,YOLOv8在处理一些复杂场景和小目标时可能存在一定的性能限制。为了克服YOLOv8的局限性,清华…

ES6: set和map数据结构以及使用场景

ES6:set和map数据结构 一、Set 数据结构&#xff1a;二、使用场景&#xff1a;使用Set 进行去重三、Map 数据结构四、使用场景&#xff1a;使用Map进行树型数据懒加载刷新五、Set和Map的区别六、Map、Set的实际使用场景 Set 和 Map 是 ES6 中引入的两种新的数据结构&#xff0c…

代码随想录算法训练营三刷day53 | 动态规划之子序列 1143.最长公共子序列 1035.不相交的线 53. 最大子序和

day53 1143.最长公共子序列1.确定dp数组&#xff08;dp table&#xff09;以及下标的含义2.确定递推公式3.dp数组如何初始化4.确定遍历顺序5.举例推导dp数组 1035.不相交的线53. 最大子序和1.确定dp数组&#xff08;dp table&#xff09;以及下标的含义2.确定递推公式3.dp数组如…

2024 十五届蓝桥杯省赛Python B组

以下仅是我的答案&#xff0c;仅供参考&#xff0c;欢迎讨论。 A&#xff1a;穿越时空之门 二进制、四进制转换。答案&#xff1a;63。 B&#xff1a;数字串个数 排除0&#xff0c;总的方案数9^10000,减去不存在3和不存在7的2*8^10000&#xff0c;再加上同时不存在3和7的7^…

Coding and Paper Letter(八十九)

CPL之第八十九期。 1 Coding: 1.openai通用代理转换是一个用于将其他厂商服务转为openai 标准接口相应的工具. 通过该工具, 可以将其他厂商的服务转为openai 标准接口. 讯飞星火,通义千问,gemini,openai,copilot,double&#xff0c;kimi&#xff0c;智谱清言 使用spring2webf…

Quantum Temple借助Sui通过NFT推动再生旅游

从金融到艺术&#xff0c;从游戏到无线网络&#xff0c;各行各业都涌现出大量初创公司&#xff0c;利用区块链技术颠覆现状。说到旅游业&#xff0c;让人联想到拥挤的机场、快节奏的旅游和豪华游轮&#xff0c;可能看起来对区块链创新持守旧态度。一家初创公司认为现在是时候改…

FreeRTOS创建第一个程序

使用freeRTOS创建任务时使用如下函数 函数的参数 创建一个FreeRTOS任务点亮led灯实现led灯500毫秒翻转一次 具体的代码实现 #include "stm32f10x.h" // Device header #include "Delay.h" #include "freeRTOS.h" #include &quo…