基于顺序表实现通讯管理系统!(有完整源码!)

news2025/1/19 20:32:31

​​​​​​​

                                                                                个人主页:秋风起,再归来~

                                                                                文章专栏:C语言实战项目                              

                                                                        个人格言:悟已往之不谏,知来者犹可追

                                                                                        克心守己,律己则安!​​​​​​​

目录

1、实现思路

​编辑

2、各种接口的实现

2.1 初始化通讯录

2.2 添加通讯录数据

2.3 删除通讯录数据

2.4 展示通讯录数据

2.5 查找通讯录数据

2.6 修改通讯录数据

2.7 销毁通讯录数据

2.8 制作一个简易的菜单 

3、完整源码

SeqList.h

Contact.h

SeqList.c

Contact.c

test.c

4、 完结散花


1、实现思路

前言:在我之前的文章当中已经写过一篇关于如何实现顺序表的文章(点击这里),而这篇文章主要是讲解如何基于顺序表实现通讯管理系统,所以要看明白这篇文章的宝子们一定要先看完写的顺序表的文章哦~

1.1 首先我们知道顺序表的底层就是数组,而通讯录就是顺序表通过封装过后的产物~

所以我们可以说通讯录的底层其实就是顺序表啦~

1.2我们知道之前实现顺序表的时候,每个数组中存放的是内置类型int,而我们如果想要将各种联系人的数据存放并管理起来,那么我们就必须先自定义一个结构体类型来存放每个联系人的数据。然后将每个联系人的数据存放到数组中统计管理起来~

我们用宏定义来表示数组的大小方便以后的调整~(这些代码都是写在contact.h头文件当中)

#define NAME_MAX 20
#define GENDER_MAX 20
#define TELE_MAX 20
#define ADDR_MAX 200
//定义一个自定义类型来存放我们所要的联系人信息
typedef struct PersonInformation
{
	char name[NAME_MAX];//名字
	char gender[GENDER_MAX];//性别
	int age;//年龄
	char tele[TELE_MAX];//电话
	char addr[ADDR_MAX];//住址
}PeoInfo;

 ​​

1.3 我们知道顺序表是这样定义的~

//定义一个动态顺序表的结构体变量
typedef struct SeqList
{
	SLDataType* arr;
	size_t num;//记录有效数据的个数
	size_t capacity;//该顺序表的容量大小
}SL;//将该结构体类型重命名为SL

我们在顺序表的头文件当中引入Contact.h头文件(因为我们要将顺序表中的每个元素改成我们自定义是类型)

​​

1.4 接下来我们就让顺序表摇身一变成为通讯录!

//前置申明
typedef struct SeqList contact;

 这里我只是给顺序表重新取了一个名字(contact)!

因为头文件之间不可以互相包含,所以我们不可以将SeqList.h中的SL进行重命名,只能通过前置声明。

到这里我们就可以对通讯录进行各种接口的实现了!

Contact.h

#define _CRT_SECURE_NO_WARNINGS

#pragma once
#define NAME_MAX 20
#define GENDER_MAX 20
#define TELE_MAX 20
#define ADDR_MAX 200

//定义一个自定义类型来存放我们所要的联系人信息
typedef struct PersonInformation
{
	char name[NAME_MAX];//名字
	char gender[GENDER_MAX];//性别
	int age;//年龄
	char tele[TELE_MAX];//电话
	char addr[ADDR_MAX];//住址
}PeoInfo;

//前置申明
typedef struct SeqList contact;

//初始化通讯录
void InitContact(contact* con);

//添加通讯录数据
void AddContact(contact* con);

//删除通讯录数据
void DelContact(contact* con);

//展示通讯录数据
void ShowContact(contact* con);

//查找通讯录数据
void FindContact(contact* con);

//修改通讯录数据
void ModifyContact(contact* con);

//销毁通讯录数据
void DestroyContact(contact* con);

SeqList.h

#define _CRT_SECURE_NO_WARNINGS

#pragma once//避免头文件的多次包含
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
#include"Contact.h"//需要自定义的类型,所以引入contact头文件
typedef PeoInfo SLDataType;//便于类型的改动

//定义一个动态顺序表的结构体变量
typedef struct SeqList
{
	SLDataType* arr;
	size_t num;//记录有效数据的个数
	size_t capacity;//该顺序表的容量大小
}SL;//将该结构体类型重命名为SL

//加入增删查改接口

//1. 顺序表初始化
void SeqListInit(SL* p);

//2. 检查顺序表容量是否已满
void CheckSeqList(SL* p);

//3. 顺序表的尾插
void SeqListPushBack(SL* p, SLDataType x);

//4. 顺序表的尾删
void SeqListPopBack(SL* p);

//5. 顺序表的头插
void SeqListPushFront(SL* p, SLDataType x);

//6. 顺序表的头删
void SeqListPopFront(SL* p);

//7. 顺序表在pos位置插入
void SeqListInsert(SL* p, size_t pos, SLDataType x);

//8. 顺序表在pos位置删除
void SeqListErase(SL* p, size_t pos);

//9. 顺序表的查找
int SeqListFind(SL* p, SLDataType x);//如果该数字存在则返回该数字的下标,否则返回-1

//10 顺序表的销毁
void SeqListDestory(SL* p);

//11. 顺序表的打印
void SeqListPrint(SL* p);

2、各种接口的实现

2.1 初始化通讯录

因为我们希望在初始化通讯录时可以将我们之前保存的数据加载到通讯中,所以我们可以通过文件操作将数据加载到通讯录当中~

//导入原文件中的数据
void DoadContact(contact* con)
{
	FILE* pf = fopen("contact.txt", "rb");
	if (pf == NULL)
	{
		perror("open fail\n");
		return;
	}
	PeoInfo info = { 0 };
	while (fread(&info, sizeof(PeoInfo), 1, pf))
	{
		SeqListPushBack(con, info);
	}
	printf("历史数据导入成功!\n");
	fclose(pf);
	pf = NULL;
}

在初始化时,我们就可以调用顺序表中的初始化接口来实现通讯录的初始化 ,然后再导入原数据~

//初始化通讯录
void InitContact(contact* con)
{
	SeqListInit(con);
	DoadContact(con);
}

2.2 添加通讯录数据

添加数据,我们就是在尾插的基础上对顺序表进行封装(头插也可以)!

//添加通讯录数据
void AddContact(contact* con)
{
	PeoInfo p;
	printf("请输入您要添加的联系人的姓名!\n");
	scanf("%s", p.name);
	printf("请输入您要添加的联系人的性别!\n");
	scanf("%s", p.gender); 
	printf("请输入您要添加的联系人的年龄!\n");
	scanf("%d", &(p.age));
	printf("请输入您要添加的联系人的电话!\n");
	scanf("%s", p.tele);
	printf("请输入您要添加的联系人的住址!\n");
	scanf("%s", p.addr);
	SeqListPushBack(con, p);
	printf("插入成功\n");
}

2.3 删除通讯录数据

这里我们通过名字来删除通讯录的数据!(当然我们也可以通过其他方式来删除数据)

//通过名字来查找通讯录中是否存在该联系人数据
int  FindByName(contact* con,char* name)
{
	for (int i = 0; i < con->num; i++)
	{
		if (strcmp(con->arr[i].name, name) == 0)
		{
			return i;//如果找到就返回他的下标
		}
	}
	return -1;//如果没找到返回一个无效的下标
}
//删除通讯录数据
void DelContact(contact* con)
{
	char name[NAME_MAX];
	printf("请输入您要删除的联系人的名字!\n");
	scanf("%s", name);
	int pos=FindByName(con, name);
	if (pos < 0)
	{
		printf("您要删除的联系人不存在!\n");
		return;
	}
	//调用顺序表中的在指定位置删除数据的函数
	SeqListErase(con, pos);
	printf("删除成功!\n");
}

2.4 展示通讯录数据

//展示通讯录数据
void ShowContact(contact* con)
{
	printf("名字\t\t性别\t\t年龄\t\t电话\t\t\t住址\n");
	for (int i = 0; i < con->num; i++)
	{
		printf("%s\t\t%s\t\t%d\t\t%s\t\t%s\n",
			con->arr[i].name,
			con->arr[i].gender,
			con->arr[i].age,
			con->arr[i].tele,
			con->arr[i].addr
		);
	}
}

2.5 查找通讯录数据

//查找通讯录数据
void FindContact(contact* con)
{
	char name[NAME_MAX];
	printf("请输入您要查找的联系人的名字!\n");
	scanf("%s", name);
	int pos = FindByName(con, name);
	if (pos < 0)
	{
		printf("您要查找的联系人不存在!\n");
		return;
	}
	printf("名字\t性别\t年龄\t电话\t住址\n");
	printf("%s\t%s\t%d\t%s\t%s\t\n",
		con->arr[pos].name,
		con->arr[pos].gender,
		con->arr[pos].age,
		con->arr[pos].tele,
		con->arr[pos].addr
	);
}

2.6 修改通讯录数据

//修改通讯录数据
void ModifyContact(contact* con)
{
	char name[NAME_MAX];
	printf("请输入您要修改的联系人的名字!\n");
	scanf("%s", name);
	int pos = FindByName(con, name);
	if (pos < 0)
	{
		printf("您要修改的联系人不存在!\n");
		return;
	}
	printf("请输入新的名字\n");
	scanf("%s", con->arr[pos].name);
	printf("请输入新的性别\n");
	scanf("%s", con->arr[pos].gender);
	printf("请输入新的年龄\n");
	scanf("%d", &con->arr[pos].age);
	printf("请输入新的电话\n");
	scanf("%s", con->arr[pos].tele);
	printf("请输入新的住址\n");
	scanf("%s", con->arr[pos].addr);
	printf("修改成功!\n");
}

2.7 销毁通讯录数据

在退出通讯录时我们希望将我们对通讯录进行的操作保存下来!

//将输入的数据保存到通讯录中
void SaveContact(contact* con)
{
	FILE* pf = fopen("contact.txt", "wb");
	if (pf == NULL)
	{
		perror("open fail\n");
		return;
	}
	PeoInfo info = { 0 };
	for (int i = 0; i < con->num; i++)
	{
		fwrite(con->arr + i, sizeof(PeoInfo), 1, pf);
	}
	printf("历史数据保存成功!\n");
	fclose(pf);
	pf = NULL;
}
//先保存数据到文件中再销毁通讯录数据
void DestroyContact(contact* con)
{
	SaveContact(con);
	//调用顺序表的销毁函数即可
	SeqListDestory(con);
}

2.8 制作一个简易的菜单 

#define _CRT_SECURE_NO_WARNINGS

#include"SeqList.h"
#include"contact.h"

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


int main()
{
	contact con = { 0 };
	InitContact(&con);
	int input = 0;
	do
	{
		menu();
		printf("请输入您的选择!\n");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			AddContact(&con);
			break;
		case 2:
			DelContact(&con);
			break;
		case 3:
			FindContact(&con);
			break;
		case 4:
			ModifyContact(&con);
			break;
		case 5:
			ShowContact(&con);
			break;
		case 0:
			printf("退出通讯录成功!\n");
			break;
		default:
			printf("输入错误,请重新选择!\n");
			break;
		}
	} while(input);
	DestroyContact(&con);
	return 0;
}

3、完整源码

SeqList.h

#define _CRT_SECURE_NO_WARNINGS

#pragma once//避免头文件的多次包含
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
#include"Contact.h"//需要自定义的类型,所以引入contact头文件
typedef PeoInfo SLDataType;//便于类型的改动

//定义一个动态顺序表的结构体变量
typedef struct SeqList
{
	SLDataType* arr;
	size_t num;//记录有效数据的个数
	size_t capacity;//该顺序表的容量大小
}SL;//将该结构体类型重命名为SL

//加入增删查改接口

//1. 顺序表初始化
void SeqListInit(SL* p);

//2. 检查顺序表容量是否已满
void CheckSeqList(SL* p);

//3. 顺序表的尾插
void SeqListPushBack(SL* p, SLDataType x);

//4. 顺序表的尾删
void SeqListPopBack(SL* p);

//5. 顺序表的头插
void SeqListPushFront(SL* p, SLDataType x);

//6. 顺序表的头删
void SeqListPopFront(SL* p);

//7. 顺序表在pos位置插入
void SeqListInsert(SL* p, size_t pos, SLDataType x);

//8. 顺序表在pos位置删除
void SeqListErase(SL* p, size_t pos);

//9. 顺序表的查找
int SeqListFind(SL* p, SLDataType x);//如果该数字存在则返回该数字的下标,否则返回-1

//10 顺序表的销毁
void SeqListDestory(SL* p);

//11. 顺序表的打印
void SeqListPrint(SL* p);

Contact.h

#define _CRT_SECURE_NO_WARNINGS

#pragma once
#define NAME_MAX 20
#define GENDER_MAX 20
#define TELE_MAX 20
#define ADDR_MAX 200

//定义一个自定义类型来存放我们所要的联系人信息
typedef struct PersonInformation
{
	char name[NAME_MAX];//名字
	char gender[GENDER_MAX];//性别
	int age;//年龄
	char tele[TELE_MAX];//电话
	char addr[ADDR_MAX];//住址
}PeoInfo;

//前置申明
typedef struct SeqList contact;

//初始化通讯录
void InitContact(contact* con);

//添加通讯录数据
void AddContact(contact* con);

//删除通讯录数据
void DelContact(contact* con);

//展示通讯录数据
void ShowContact(contact* con);

//查找通讯录数据
void FindContact(contact* con);

//修改通讯录数据
void ModifyContact(contact* con);

//销毁通讯录数据
void DestroyContact(contact* con);

SeqList.c

#define _CRT_SECURE_NO_WARNINGS
#include"SeqList.h"
//1. 顺序表初始化
void SeqListInit(SL* p)
{
	assert(p);//判断指针的有效性
	p->arr = NULL;
	p->capacity = 0;
	p->num = 0;
}

//2. 检查顺序表容量是否已满
void CheckSeqList(SL* p)
{
	assert(p);//判断指针的有效性
	if (p->num == p->capacity)
	{
		size_t newcapacity = p->capacity == 0 ? p->capacity = 4 : p->capacity * 2;
		//如果原来没有空间,就给上4,有的话就扩大为原来的两倍
		SLDataType* ptr = (SLDataType*)realloc(p->arr, newcapacity * sizeof(SLDataType));//动态扩容
		if (ptr == NULL)
		{
			perror("realloc fail;");
			return;
		}
		//也可以用assert断言一下
		p->arr = ptr;//开辟成功将地址传给arr
		p->capacity = newcapacity;//更新容量
	}
}

//3. 顺序表的尾插
void SeqListPushBack(SL* p, SLDataType x)
{
	assert(p);//判断指针的有效性
	CheckSeqList(p);//尾插前先判断有没有容量或容量够不够
	p->arr[p->num] = x;//尾部插入数据
	p->num++;//有效数加一
}

//4. 顺序表的尾删
void SeqListPopBack(SL* p)
{
	assert(p);//判断指针的有效性
	assert(p->num > 0);//断言存在有效数据
	p->num--;//尾删一个数据
}

//5. 顺序表的头插
void SeqListPushFront(SL* p, SLDataType x)
{
	assert(p);//判断指针的有效性
	CheckSeqList(p);//先判断容量是否满了
	size_t end = p->num;
	while (end)
	{
		p->arr[end] = p->arr[end - 1];//整体向后移动
		end--;
	}
	p->arr[0] = x;//头插
	p->num++;//有效数据加一
}

//6. 顺序表的头删
void SeqListPopFront(SL* p)
{
	assert(p);//判断指针的有效性
	assert(p->num > 0);//有数据才删除
	size_t begin = 1;
	while (begin < p->num)
	{
		p->arr[begin - 1] = p->arr[begin];//整体向前移动
		begin++;
	}
	p->num--;// 有效数据减一

}

//7. 顺序表在pos位置插入
void SeqListInsert(SL* p, size_t pos, SLDataType x)
{
	assert(p);//判断指针的有效性
	assert(pos >= 0 && pos < p->num);//pos必须小于num并且大于等于0
	CheckSeqList(p);//判断容量是否满了
	for (int i = p->num; i > pos - 1; i--)
	{
		p->arr[i] = p->arr[i - 1];//将pos后面的元素往后挪
	}
	p->arr[pos - 1] = x;//在pos位置加入数据
	p->num++;//有效个数加一
}

//8. 顺序表在pos位置删除
void SeqListErase(SL* p, size_t pos)
{
	assert(p);//判断指针的有效性
	assert(pos >= 0 && pos < p->num);//pos必须小于num并且大于等于0
	assert(p->num > 0);//有数据才能删除
	for (int i = pos; i < p->num-1; i++)
	{
		p->arr[i] = p->arr[i+1];//将pos后面的元素往后挪
	}
	p->num--;//有效个数减一
}

//9. 顺序表的查找
int SeqListFind(SL* p, SLDataType x)//如果该数字存在则返回该数字的下标,否则返回-1
{
	assert(p);//断言
	for (int i = 0; i < p->num; i++)
	{
		if (p->arr[i] == x)
		{
			return i;//查到返回下标
		}
	}
	return -1;//没有查到
}


//10 顺序表的销毁
void SeqListDestory(SL* p)
{
	assert(p);//判断指针的有效性
	free(p->arr);//释放动态内存开辟的空间
	p->arr = NULL;
	p->capacity = 0;//容量置为0
	p->num = 0;//有效个数置为0
}

//11. 顺序表的打印
void SeqListPrint(SL* p)
{
	assert(p);//判断指针的有效性
	if (p->num == 0)
	{
		printf("顺序表为空!\n");
		return;
	}
	for (int i = 0; i < p->num; i++)
	{
		printf("%d ", p->arr[i]);//打印数据
	}
	printf("\n");
}

Contact.c

#define _CRT_SECURE_NO_WARNINGS

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


//导入原文件中的数据
void DoadContact(contact* con)
{
	FILE* pf = fopen("contact.txt", "rb");
	if (pf == NULL)
	{
		perror("open fail\n");
		return;
	}
	PeoInfo info = { 0 };
	while (fread(&info, sizeof(PeoInfo), 1, pf))
	{
		SeqListPushBack(con, info);
	}
	printf("历史数据导入成功!\n");
	fclose(pf);
	pf = NULL;
}


//初始化通讯录
void InitContact(contact* con)
{
	SeqListInit(con);
	DoadContact(con);
}

//添加通讯录数据
void AddContact(contact* con)
{
	PeoInfo p;
	printf("请输入您要添加的联系人的姓名!\n");
	scanf("%s", p.name);
	printf("请输入您要添加的联系人的性别!\n");
	scanf("%s", p.gender); 
	printf("请输入您要添加的联系人的年龄!\n");
	scanf("%d", &(p.age));
	printf("请输入您要添加的联系人的电话!\n");
	scanf("%s", p.tele);
	printf("请输入您要添加的联系人的住址!\n");
	scanf("%s", p.addr);
	SeqListPushBack(con, p);
	printf("插入成功\n");
}

//通过名字来查找通讯录中是否存在该联系人数据
int  FindByName(contact* con,char* name)
{
	for (int i = 0; i < con->num; i++)
	{
		if (strcmp(con->arr[i].name, name) == 0)
		{
			return i;//如果找到就返回他的下标
		}
	}
	return -1;//如果没找到返回一个无效的下标
}

//删除通讯录数据
void DelContact(contact* con)
{
	char name[NAME_MAX];
	printf("请输入您要删除的联系人的名字!\n");
	scanf("%s", name);
	int pos=FindByName(con, name);
	if (pos < 0)
	{
		printf("您要删除的联系人不存在!\n");
		return;
	}
	//调用顺序表中的在指定位置删除数据的函数
	SeqListErase(con, pos);
	printf("删除成功!\n");
}

//展示通讯录数据
void ShowContact(contact* con)
{
	printf("名字\t\t性别\t\t年龄\t\t电话\t\t\t住址\n");
	for (int i = 0; i < con->num; i++)
	{
		printf("%s\t\t%s\t\t%d\t\t%s\t\t%s\n",
			con->arr[i].name,
			con->arr[i].gender,
			con->arr[i].age,
			con->arr[i].tele,
			con->arr[i].addr
		);
	}
}


//查找通讯录数据
void FindContact(contact* con)
{
	char name[NAME_MAX];
	printf("请输入您要查找的联系人的名字!\n");
	scanf("%s", name);
	int pos = FindByName(con, name);
	if (pos < 0)
	{
		printf("您要查找的联系人不存在!\n");
		return;
	}
	printf("名字\t性别\t年龄\t电话\t住址\n");
	printf("%s\t%s\t%d\t%s\t%s\t\n",
		con->arr[pos].name,
		con->arr[pos].gender,
		con->arr[pos].age,
		con->arr[pos].tele,
		con->arr[pos].addr
	);
}

//修改通讯录数据
void ModifyContact(contact* con)
{
	char name[NAME_MAX];
	printf("请输入您要修改的联系人的名字!\n");
	scanf("%s", name);
	int pos = FindByName(con, name);
	if (pos < 0)
	{
		printf("您要修改的联系人不存在!\n");
		return;
	}
	printf("请输入新的名字\n");
	scanf("%s", con->arr[pos].name);
	printf("请输入新的性别\n");
	scanf("%s", con->arr[pos].gender);
	printf("请输入新的年龄\n");
	scanf("%d", &con->arr[pos].age);
	printf("请输入新的电话\n");
	scanf("%s", con->arr[pos].tele);
	printf("请输入新的住址\n");
	scanf("%s", con->arr[pos].addr);
	printf("修改成功!\n");
}

//将输入的数据保存到通讯录中
void SaveContact(contact* con)
{
	FILE* pf = fopen("contact.txt", "wb");
	if (pf == NULL)
	{
		perror("open fail\n");
		return;
	}
	PeoInfo info = { 0 };
	for (int i = 0; i < con->num; i++)
	{
		fwrite(con->arr + i, sizeof(PeoInfo), 1, pf);
	}
	printf("历史数据保存成功!\n");
	fclose(pf);
	pf = NULL;
}

//先保存数据到文件中再销毁通讯录数据
void DestroyContact(contact* con)
{
	SaveContact(con);
	//调用顺序表的销毁函数即可
	SeqListDestory(con);
}

test.c

#define _CRT_SECURE_NO_WARNINGS

#include"SeqList.h"
#include"contact.h"

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


int main()
{
	contact con = { 0 };
	InitContact(&con);
	int input = 0;
	do
	{
		menu();
		printf("请输入您的选择!\n");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			AddContact(&con);
			break;
		case 2:
			DelContact(&con);
			break;
		case 3:
			FindContact(&con);
			break;
		case 4:
			ModifyContact(&con);
			break;
		case 5:
			ShowContact(&con);
			break;
		case 0:
			printf("退出通讯录成功!\n");
			break;
		default:
			printf("输入错误,请重新选择!\n");
			break;
		}
	} while(input);
	DestroyContact(&con);
	return 0;
}

4、 完结散花

好了,这期的分享到这里就结束了~

如果这篇博客对你有帮助的话,可以用你们的小手指点一个免费的赞并收藏起来哟~

如果期待博主下期内容的话,可以点点关注,避免找不到我了呢~

我们下期不见不散~~

​​​​

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

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

相关文章

从B2B转向B2B2C模式:工业品牌史丹利百得的转型历程

图片来源&#xff1a;Twitter 在当今数据驱动的营销环境中&#xff0c;企业努力更好了解客户&#xff0c;并在整个客户旅程中提供个性化体验。史丹利百得&#xff08;Stanley Black & Decker&#xff09;是一家领先的工具和工业设备供应商&#xff0c;近年来开始重大转型。…

Oracle的物理结构解析

这些图是我自己画的&#xff0c;我也会在我的公众号【会用数据库】解析。理解起来非常简单&#xff0c;而且非常好记。不用死记硬背&#xff0c;有兴趣可以来公众号看呀。

深度学习【向量化(array)】

为什么要向量化 在深度学习安全领域、深度学习练习中&#xff0c;你经常发现在训练大量数据时&#xff0c;深度学习算法表现才更加优越&#xff0c;所以你的代码运行的非常快至关重要&#xff0c;否则&#xff0c;你将要等待非常长的时间去得到结果。所以在深度学习领域向量化…

Apache Pulsar源码解析之Lookup机制

引言 在学习Pulsar一段时间后&#xff0c;相信大家也或多或少听说Lookup这个词&#xff0c;今天就一起来深入剖析下Pulsar是怎么设计的它吧 Lookup是什么 在客户端跟服务端建立TCP连接前有些信息需要提前获取&#xff0c;这个获取方式就是Lookup机制。所获取的信息有以下几种…

机器学习实战18-机器学习中XGBClassifier分类器模型的应用实战,以及XGBClassifier分类器的调优策略

大家好&#xff0c;我是微学AI&#xff0c;今天给大家介绍一下机器学习实战18-机器学习中XGBClassifier分类器模型的应用实战&#xff0c;以及XGBClassifier分类器的调优策略。XGBClassifier是基于eXtreme Gradient Boosting (XGBoost)算法的分类器模型&#xff0c;在机器学习领…

成为图像SoC大牛有多难?

IPC&#xff08;Internet Protocol Camera&#xff0c;即网络摄像机&#xff09;芯片架构师需要具备一系列跨学科的知识和技能。IPC芯片架构师的工作涉及到先进工艺、低功耗、SoC架构、处理器架构、图像处理、视频压缩、网络通信以及嵌入式系统设计等多个领域。以下是一些关键的…

Ubuntu22.04中基于Qt开发Android App

文章目录 前言在Ubuntu22.04中配置开发环境案例测试参考 前言 使用Qt开发手机应用程序是一种高效且灵活的选择。Qt作为一个跨平台的开发框架&#xff0c;为开发者提供了统一的开发体验和丰富的功能库。首先&#xff0c;Qt的跨平台性让开发者可以使用相同的代码库在不同的操作系…

收藏|深入浅出分析光刻机

光刻技术是指在光照作用下&#xff0c;借助光致抗蚀剂&#xff08;又名光刻胶&#xff09;将掩膜版上的图形转移到基片上的技术。 光刻机是半导体生产制造的主要生产设备之一&#xff0c;也是决定整个半导体生产工艺水平高低的核心技术机台。半导体技术发展都是以光刻机的光刻线…

【测试开发学习历程】python流程控制

前言&#xff1a;写到这里也许自己真的有些疲惫了&#xff0c;但是人生不就是像西西弗斯推石上山一样的枯燥乏味吗&#xff1f; 在python当中的流程控制主要包含以下两部分的内容&#xff1a; 条件判断 循环 1 条件判断 条件判断用if语句实现&#xff0c;if语句的几种格式…

微软detours代码借鉴点备注

comeasy 借鉴点1 Loadlibray的时间选择 注入库wrotei.dll&#xff0c;为了获取istream的接口&#xff0c;需要loadlibrary&#xff0c;但是在dllmain中是不建议这样做的。因此&#xff0c;动态库在dllmain的时候直接挂载了comeasy.exe的入口 //获取入口 TrueEntryPoint (i…

太阳能光伏储能系统:全周期一站式解决方案

随着全球能源结构的不断变革&#xff0c;清洁能源的重要性日益凸显。太阳能光伏储能系统作为一种高效、环保的能源解决方案&#xff0c;正逐渐成为推动能源转型的关键力量。本文将详细介绍太阳能光伏储能系统的全周期一站式解决方案&#xff0c;以期为读者提供全面、深入的了解…

动态多目标优化:动态约束多目标优化测试集DCP1-DCP9的TruePF(提供MATLAB代码)

一、进化动态约束多目标优化测试集DCP1-DCP9 参考文献&#xff1a; [1]G. Chen, Y. Guo, Y. Wang, J. Liang, D. Gong and S. Yang, “Evolutionary Dynamic Constrained Multiobjective Optimization: Test Suite and Algorithm,” in IEEE Transactions on Evolutionary Com…

聚能共创下一代智能终端操作系统 软通动力荣膺“OpenHarmony优秀贡献单位”

近日&#xff0c;由开放原子开源基金会指导&#xff0c;以“开源共享未来”为主题的OpenHarmony社区年会在北京成功举办。本次活动汇集OpenHarmony项目群共建单位及生态伙伴等多方力量&#xff0c;旨在对2023年度OpenHarmony年度开源事业全面总结的同时&#xff0c;吸引更多伙伴…

VSCode如何调试C#代码?

1、启动VSCode&#xff1b; 一、创建项目 1、创建一个文件夹(workspace)&#xff1a; 2、进入这个文件夹 cd tt1 3、创建解决方案 dotnet new sln -o MyApp 4、进入解决方案 cd .\MyApp\ 5、创建项目&#xff08;在此假定为一个命令行的项目&#xff09; dotnet new …

PCIe 7.0|不要太卷,劝你先躺平

PCIe 6.0都已经发布了2-3年了&#xff0c;目前业内生态还没完全建立。甚至很多人都还没用上PCIe 5.0呢&#xff01; 近日&#xff0c;PCIe 7.0 ver0.5版本已经开放&#xff0c;同时宣布马不停蹄准备在2025年完成正式SPEC规范发布。 回顾PCIe 7.0变更&#xff0c;PCI-SIG在2022年…

力扣1448---统计二叉树中好节点的数量(Java、DFS、中等题)

题目描述&#xff1a; 给你一棵根为 root 的二叉树&#xff0c;请你返回二叉树中好节点的数目。 「好节点」X 定义为&#xff1a;从根到该节点 X 所经过的节点中&#xff0c;没有任何节点的值大于 X 的值。 示例 1&#xff1a; 输入&#xff1a;root [3,1,4,3,null,1,5] 输出…

SSM项目实战——哈哈音乐(四)前台模块开发

1、项目准备 ①导入依赖和前端资源 <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.x…

Educational Codeforces Round 162 (Rated for Div. 2) ----- E. Count Paths --- 题解

E. Count Paths&#xff1a; 题目大意&#xff1a; 思路解析&#xff1a; 根据题目中定义的美丽路径&#xff0c;我们可以发现路径只有两种情况&#xff1a; 当前结点作为起始结点&#xff0c;那我们只需要知道它的子树下有多少个相同颜色的结点&#xff0c;并且相同颜色的结…

攻防世界:mfw[WriteUP]

根据题目提示考虑是git库泄露 这里在地址栏后加.git也可以验证是git库泄露 使用GitHack工具对git库进行恢复重建 在templates目录下存在flag.php文件&#xff0c;但里面并没有flag 有内容的只有主目录下的index.php index.php源码&#xff1a; <?phpif (isset($_GET[page…

2024年最新版FL Studio21.2.3 Build 4004 for Mac 版激活下载和图文激活教程

FL studio21中文别名水果编曲软件&#xff0c;是一款全能的音乐制作软件&#xff0c;包括编曲、录音、剪辑和混音等诸多功能&#xff0c;让你的电脑编程一个全能的录音室&#xff0c;它为您提供了一个集成的开发环境&#xff0c;使用起来非常简单有效&#xff0c;您的工作会变得…