通讯录的实现(未优化的完全版)

目录

一、前言

二、通讯录的实现

1.关于通讯录的前期准备

(1)关于全局变量的定义

(2)菜单的实现

(3)关于联系人结构体的创建

(4)实现菜单选项的功能

2、通讯录的功能实现

(1)初始化通讯录

(2)增加联系人

(3)删除联系人 

(4)打印通讯录

 (5)查找联系人

(6)修改联系人

 (7)排序通讯录

 总结:

test.c

 contact.c

 contact.h

 感谢阅读!!!


一、前言

本文将会用c语言实现一个通讯录的系统,并且存储若干人的信息,每个人的信息包括:姓名,性别,年龄,电话号码,住址。此通讯录系统的功能包括: 1.增加联系人 2.删除对应的联系人 3.查找联系人 4.修改联系人的信息 5.排序此通讯录 6.打印出通讯录每个人的信息

二、通讯录的实现

1.关于通讯录的前期准备

(1)关于全局变量的定义

为了实现这些变量,并且方便后期的处理数组大小,所以我们可以利用宏来实现这个功能

#define MAX 1000

#define MAX_NAME 20
#define MAX_SEX 5
#define MAX_TELE 12
#define MAX_ADDR 30
(2)菜单的实现

首先关于一个通讯录,建立一个菜单是很重要的,菜单能够实现和用户的交互。

因此我们需要建立一个菜单,并且菜单立马应该包括通讯录立马该有的功能,以便于用户的操作

代码如下:

void menu()
{
	printf("**************************************\n");
	printf("*****    1.add        2.del      *****\n");
	printf("*****    3.search     4.modify   *****\n");
	printf("*****    5.show       6sort      *****\n");
	printf("*****    0.exit                  *****\n");
	printf("**************************************\n");
}

效果大致这样就可以;

(3)关于联系人结构体的创建

这里我们需要利用结构体来实现实现前言中的通讯录功能以及联系人信息,我将利用两个结构体来构建我们需要的东西。(大小设置为1000)(最多存放1000个人的信息)

struct PeoInfo
{
	char name[MAX_NAME];
	int age;
	char sex[MAX_SEX];
	char tele[MAX_TELE];
	char addr[MAX_ADDR];
};

struct contact
{
	struct PeoInfo date[MAX];
	int size;
};
(4)实现菜单选项的功能

我们需要根据菜单里面的选项来选择进行我们需要实现的功能,比如我们想假如一个用户信息,我们就输入1就会进行用户假如的操作,我们想退出程序我们输入0就可以退出。我选择利用枚举变量的形式来实现,讲操作变成数字,利用switch选择语句来实现各自的功能。

使用枚举的好处就是方便了我们补充函数内容的时候方便得知那个数字对应那个功能

enum option
{
	EXIT,//0
	ADD,//1
	DEL,//2
	SEARCH,//3
	MODIFY,//4
	SHOW, //5
	SORT,//6
};

然后使用switch的时候便会方便许多,如下

	int input = 0;
	//创建结构体数组
	struct contact con;
	//初始化结构体数组
	Initcon(&con);
do {
	menu();
	printf("请输入你的选择:>");
	scanf("%d", &input);
	switch (input)
	{
	case ADD:
		Addcontact(&con);
		break;
	case DEL:
		Delcontact(&con);
		break;
	case SEARCH:
		Searchcontact(&con);
		break;
	case MODIFY:
		Modifycontact(&con);
		break;
	case SHOW:
		Showcontact(&con);
		break;
	case SORT:
		SortContact(&con);
		break;
	case EXIT:
		printf("退出通讯录\n");
		break;
	default:
		printf("输入错误,请重新输入:>\n");
		break;
	}

} while (input);

我们case的后面不在是1 2 3 而是对应功能的名字,是不是很方便呢

2、通讯录的功能实现

(1)初始化通讯录

第一步初始化的话,我们要知道要将通讯录初始化什么内容,初始化的目的就是为了避免因不进行初始化导致存的是随机值,从而造成不必要的麻烦,一般的初始化就是放0或者为空;这里我们可以浅浅用一个memset函数来实现,当然别忘了引用string的头文件,然后sz的初始化很简单就是初始化为0。

	memset(ps->date, 0, sizeof(ps->date));
	ps->size = 0;

代码就是这么简单,但是我们为了书写的时候便于看,一般分多个项目进行写一个小游戏;

这里只展示函数的实现部分(下同)

void Initcon(struct contact* ps)
{
	assert(ps!=NULL);
	memset(ps->date, 0, sizeof(ps->date));
	ps->size = 0;
}
(2)增加联系人

首先第一步我们完成第一步就可以创建关于加入联系人的函数,这个很简单我们只需要访问通讯录结构体里面的数组中的每个元素然后输入对应值就可以了

void Addcontact(struct contact* ps)
{
	assert(ps != NULL);
	if (ps->size == MAX)
	{
		printf("通讯录已满,无法再进行添加\n");
	}
	else
	{
		printf("情输入姓名:>");
		scanf("%s", ps->date[ps->size].name);
		printf("情输入年龄:>");
		scanf("%d", &(ps->date[ps->size].age));
		printf("情输入性别:>");
		scanf("%s", ps->date[ps->size].sex);
		printf("情输入电话:>");
		scanf("%s", ps->date[ps->size].tele);
		printf("情输入地址:>");
		scanf("%s", ps->date[ps->size].addr);

		ps->size++;//千万要记得++

		printf("录入信息完成\n");
	}
}

(3)删除联系人 

这个操作也不算复杂,我的思路是,首先我们先利用刚刚查找的嘞个查找下标的函数,查找到我们需要寻找删除联系人的坐标,然后对他进行删除,删除之后呢我们需要把后面的元素挨个往前移动,这就要利用for循环,但是对于for循环的次数要多加注意,因为稍不小心就会导致数组越界。

static int Find_by_name(const struct contact* ps, char name[MAX_NAME])
{//static修饰可以使其函数仅可以再本。c生效
	//避免了污染
	assert(ps != NULL);
	int i = 0;
	for (i = 0; i < ps->size; i++)
	{
		if (strcmp(ps->date[i].name, name) == 0)
			return i;
	}
	return -1;
}
void Delcontact(struct contact* ps)
{
	assert(ps != NULL);
	char name[MAX_NAME];
	printf("请输入要删除联系人的姓名:>");
	scanf("%s", name);
	//查找
	//找到返回pos下标
	//找不到返回-1
	int pos=Find_by_name(ps, name);
	if (pos == -1)
	{
		printf("要删除的联系人不存在\n");
	}
	else
	{
		int j = 0;
		for (j = pos; j <ps->size ; j++)//
			//*******
		{
			ps->date[j] = ps->date[j + 1];
		}
		ps->size--;
		printf("删除成功\n");
	}
}

 

 这个代码其中有一个地方加了 static 这一部分就很妙,就好比如如果别的。c文件再写的时候跟这个函数有关系,就可以避免发生关系,就会使得 Find_by_name这个函数只会在本文件下生效,避免了污染,就好比生物上的物种感染,你可以不用,但不能没有,避免发生麻烦;

(4)打印通讯录

打印通讯录也很简单,利用一个for循环根据sz的大小遍历结构体中的数组每个元素并且打印即可

在正常情况下打印这一步一定要尽早实现,因为,我们每写完一项功能,我们自己认为没问题,并且也可以跑的情况下,我们无法得知跟我们想要实现的功能有什么差别,这时候都需要打印一下,实践出真理;

代码如下:

void Showcontact(const struct contact* ps)
{
	assert(ps != NULL);
	int i = 0;
	if (ps->size == 0)
	{
		printf("通讯录内容为空,无法打印\n");
	}
	else
	{
		for (i = 0; i < ps->size; i++)
		{
			printf("%-20s\t%-3s\t%-5s\t%-12s\t%-20s\n", "姓名", "年龄", "性别", "电话", "地址");//为了打印出来的内容对其,显得好看对其的打印要一直
			printf("%-20s\t%-3d\t%-5s\t%-12s\t%-20s\n",//就先这跟上面的一样才好看
				ps->date[i].name,
				ps->date[i].age,
				ps->date[i].sex,
				ps->date[i].tele,
				ps->date[i].addr);
		}
		}
}

 

 (5)查找联系人

查找联系人这边我们需要构建一个函数,这个函数需要去根据我们想要寻找的姓名去在通讯录中寻找这个人所对应的位置,加入找到了就可以返回对应位置的下标,否则返回-1。找到之后就和打印通讯录的操作差不多打印出来就好了。然而查找可以通过多种方式,年龄啊,电话啊,这里使用的是姓名


void Searchcontact(const struct contact* ps)
{
	assert(ps != NULL);
	char name[MAX_NAME];
	printf("请输入要查找联系人的姓名:>");
	scanf("%s", name);
	int pos = Find_by_name(ps, name);
	if (pos == -1)
	{
		printf("要查找的联系人不存在\n");
	}
	else
	{
		printf("信息如下:\n");
		printf("%-20s\t%-3s\t%-5s\t%-12s\t%-20s\n", "姓名", "年龄", "性别", "电话", "地址");
		printf("%-20s\t%-3d\t%-5s\t%-12s\t%-20s\n",
			ps->date[pos].name,
			ps->date[pos].age,
			ps->date[pos].sex,
			ps->date[pos].tele,
			ps->date[pos].addr);
	}
}
(6)修改联系人
 

所有,我们可以先让用户输入想要修改人的信息,然后再重新在add所有信息


void Modifycontact(struct contact* ps)
{
	assert(ps != NULL);
	char name[MAX_NAME];
	printf("请输入要修改联系人的姓名:>");
	scanf("%s", name);
	int pos = Find_by_name(ps, name);
	if (pos == -1)
	{
		printf("要修改的联系人不存在\n");
	}
	else
	{
		printf("情输入姓名:>");
		scanf("%s", ps->date[pos].name);
		printf("情输入年龄:>");
		scanf("%d", &(ps->date[pos].age));
		printf("情输入性别:>");
		scanf("%s", ps->date[pos].sex);
		printf("情输入电话:>");
		scanf("%s", ps->date[pos].tele);
		printf("情输入地址:>");
		scanf("%s", ps->date[pos].addr);
		printf("修改信息完成\n");
	}
}

 但是这样写代码不免显得我们不是很nb,直接替换所有的内容,这样也会让一些本来就不用修改的信息又被修改了一遍,这太不专业了。

我们不妨先查找到需要修改人,然后先让用户查找到需要修改的这个人然后选择是修改什么信息,然后重新输入改后的信息,这个其实就和菜单选项实现很相似,我们需要利用枚举变量,跟do。。。while

enum Information
{
	ERRO,
	NAME,
	AGE,
	SEX,
	TELE,
	ADDR,
};
void Modifycontact(struct contact* ps)
{
	assert(ps != NULL);
	char name[MAX_NAME];
	printf("请输入要修改联系人的姓名:>");
	scanf("%s", name);
	int pos = Find_by_name(ps, name);
	if (pos == -1)
	{
		printf("要修改的联系人不存在\n");
	}
	else
	{
		int input = 0;
		do
		{
			printf("请输入你想修改此用户的哪项信息\n");
			printf(" 0.退出 1.姓名 2.年龄 3.性别 4.电话 5.地址:>\n");
			scanf("%d", &input);
			switch (input)
			{
			case NAME:
				printf("情输入姓名:>");
				scanf("%s", ps->date[pos].name);
				break;
			case AGE:
				printf("情输入年龄:>");
				scanf("%d", &(ps->date[pos].age));
				break;
			case SEX:
				printf("情输入性别:>");
				scanf("%s", ps->date[pos].sex);
				break;
			case TELE:
				printf("情输入电话:>");
				scanf("%s", ps->date[pos].tele);
				break;
			case ADDR:
				printf("情输入地址:>");
				scanf("%s", ps->date[pos].addr);
				break;
			case ERRO:
				printf("修改完成\n");
				break;
			default:
				printf("输入错误,请重新输入:>\n");
				break;
			}
		} while (input);
	}
}

 值得注意的是

这里的第一个没有写EXIT,而是ERRO是因为我们第一次使用枚举的时候已经定义过EXIT了再次定义会有错误,重定义

效果如下

 (7)排序通讯录

这一步如果单靠我们自己实现是很麻烦的,但是c语言的库函数里面右qsort,使用该库函数实现起来就非常的简单

int con_name(const void* e1, const void* e2)
{
	return (strcmp(((struct contact*)e1)->date->name, ((struct contact*)e2)->date->name));
}//这里一定要记得强制类型转换
void SortContact(struct contact* ps)
{
	assert(ps);
	if (ps->size == 0)
	{
		printf("通讯录为空,无法排序\n");
		return;
	}
	qsort(ps->date, ps->size, sizeof(ps->date[0]), con_name);
	printf("排序成功\n");
	Showcontact(ps); 
}

重要的内容说三遍

再写con_name时要记得强制类型转换!

再写con_name时要记得强制类型转换!

再写con_name时要记得强制类型转换!

 总结:

test.c

#define  _CRT_SECURE_NO_WARNINGS

#include"contact.h"

void menu()
{
	printf("**************************************\n");
	printf("*****    1.add        2.del      *****\n");
	printf("*****    3.search     4.modify   *****\n");
	printf("*****    5.show       6sort      *****\n");
	printf("*****    0.exit                  *****\n");
	printf("**************************************\n");
}
int main()
{
	int input = 0;
	//创建结构体数组
	struct contact con;
	//初始化结构体数组
	Initcon(&con);
	do {
		menu();
		printf("请输入你的选择:>");
		scanf("%d", &input);
		switch (input)
		{
		case ADD:
			Addcontact(&con);
			break;
		case DEL:
			Delcontact(&con);
			break;
		case SEARCH:
			Searchcontact(&con);
			break;
		case MODIFY:
			Modifycontact(&con);
			break;
		case SHOW:
			Showcontact(&con);
			break;
		case SORT:
			SortContact(&con);
			break;
		case EXIT:
			printf("退出通讯录\n");
			break;
		default:
			printf("输入错误,请重新输入:>\n");
			break;
		}

	} while (input);
	return 0;
}

 contact.c

#define  _CRT_SECURE_NO_WARNINGS

#include"contact.h"

void Initcon(struct contact* ps)
{
	assert(ps!=NULL);
	memset(ps->date, 0, sizeof(ps->date));
	ps->size = 0;
}

void Addcontact(struct contact* ps)
{
	assert(ps != NULL);
	if (ps->size == MAX)
	{
		printf("通讯录已满,无法再进行添加\n");
	}
	else
	{
		printf("情输入姓名:>");
		scanf("%s", ps->date[ps->size].name);
		printf("情输入年龄:>");
		scanf("%d", &(ps->date[ps->size].age));
		printf("情输入性别:>");
		scanf("%s", ps->date[ps->size].sex);
		printf("情输入电话:>");
		scanf("%s", ps->date[ps->size].tele);
		printf("情输入地址:>");
		scanf("%s", ps->date[ps->size].addr);
		ps->size++;
		printf("录入信息完成\n");
	}
}

void Showcontact(const struct contact* ps)
{
	assert(ps != NULL);
	int i = 0;
	if (ps->size == 0)
	{
		printf("通讯录内容为空,无法打印\n");
	}
	else
	{
		for (i = 0; i < ps->size; i++)
		{
			printf("%-20s\t%-3s\t%-5s\t%-12s\t%-20s\n", "姓名", "年龄", "性别", "电话", "地址");
			printf("%-20s\t%-3d\t%-5s\t%-12s\t%-20s\n",
				ps->date[i].name,
				ps->date[i].age,
				ps->date[i].sex,
				ps->date[i].tele,
				ps->date[i].addr);
		}
		}
}

static int Find_by_name(const struct contact* ps, char name[MAX_NAME])
{//static修饰可以使其函数仅可以再本。c生效
	//避免了污染
	assert(ps != NULL);
	int i = 0;
	for (i = 0; i < ps->size; i++)
	{
		if (strcmp(ps->date[i].name, name) == 0)
			return i;
	}
	return -1;
}
void Delcontact(struct contact* ps)
{
	assert(ps != NULL);
	char name[MAX_NAME];
	printf("请输入要删除联系人的姓名:>");
	scanf("%s", name);
	//查找
	//找到返回pos下标
	//找不到返回-1
	int pos=Find_by_name(ps, name);
	if (pos == -1)
	{
		printf("要删除的联系人不存在\n");
	}
	else
	{
		int j = 0;
		for (j = pos; j <ps->size ; j++)//
			//*******
		{
			ps->date[j] = ps->date[j + 1];
		}
		ps->size--;
		printf("删除成功\n");
	}
}

void Searchcontact(const struct contact* ps)
{
	assert(ps != NULL);
	char name[MAX_NAME];
	printf("请输入要查找联系人的姓名:>");
	scanf("%s", name);
	int pos = Find_by_name(ps, name);
	if (pos == -1)
	{
		printf("要查找的联系人不存在\n");
	}
	else
	{
		printf("信息如下:\n");
		printf("%-20s\t%-3s\t%-5s\t%-12s\t%-20s\n", "姓名", "年龄", "性别", "电话", "地址");
		printf("%-20s\t%-3d\t%-5s\t%-12s\t%-20s\n",
			ps->date[pos].name,
			ps->date[pos].age,
			ps->date[pos].sex,
			ps->date[pos].tele,
			ps->date[pos].addr);
	}
}

//void Modifycontact(struct contact* ps)
//{
//	assert(ps != NULL);
//	char name[MAX_NAME];
//	printf("请输入要修改联系人的姓名:>");
//	scanf("%s", name);
//	int pos = Find_by_name(ps, name);
//	if (pos == -1)
//	{
//		printf("要修改的联系人不存在\n");
//	}
//	else
//	{
//		printf("情输入姓名:>");
//		scanf("%s", ps->date[pos].name);
//		printf("情输入年龄:>");
//		scanf("%d", &(ps->date[pos].age));
//		printf("情输入性别:>");
//		scanf("%s", ps->date[pos].sex);
//		printf("情输入电话:>");
//		scanf("%s", ps->date[pos].tele);
//		printf("情输入地址:>");
//		scanf("%s", ps->date[pos].addr);
//		printf("修改信息完成\n");
//	}
//}


void Modifycontact(struct contact* ps)
{
	assert(ps != NULL);
	char name[MAX_NAME];
	printf("请输入要修改联系人的姓名:>");
	scanf("%s", name);
	int pos = Find_by_name(ps, name);
	if (pos == -1)
	{
		printf("要修改的联系人不存在\n");
	}
	else
	{
		int input = 0;
		do
		{
			printf("请输入你想修改此用户的哪项信息\n");
			printf(" 0.退出 1.姓名 2.年龄 3.性别 4.电话 5.地址:>\n");
			scanf("%d", &input);
			switch (input)
			{
			case NAME:
				printf("情输入姓名:>");
				scanf("%s", ps->date[pos].name);
				break;
			case AGE:
				printf("情输入年龄:>");
				scanf("%d", &(ps->date[pos].age));
				break;
			case SEX:
				printf("情输入性别:>");
				scanf("%s", ps->date[pos].sex);
				break;
			case TELE:
				printf("情输入电话:>");
				scanf("%s", ps->date[pos].tele);
				break;
			case ADDR:
				printf("情输入地址:>");
				scanf("%s", ps->date[pos].addr);
				break;
			case ERRO:
				printf("修改完成\n");
				break;
			default:
				printf("输入错误,请重新输入:>\n");
				break;
			}
		} while (input);
	}
}



int con_name(const void* e1, const void* e2)
{
	return (strcmp(((struct contact*)e1)->date->name, ((struct contact*)e2)->date->name));
}
void SortContact(struct contact* ps)
{
	assert(ps);
	if (ps->size == 0)
	{
		printf("通讯录为空,无法排序\n");
		return;
	}
	qsort(ps->date, ps->size, sizeof(ps->date[0]), con_name);
	printf("排序成功\n");
	Showcontact(ps); 
}

 contact.h

#define  _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<assert.h>
#include<stdlib.h>

#define MAX 1000

#define MAX_NAME 20
#define MAX_SEX 5
#define MAX_TELE 12
#define MAX_ADDR 30

enum option
{
	EXIT,
	ADD,
	DEL,
	SEARCH,
	MODIFY,
	SHOW, 
	SORT,
};
enum Information
{
	ERRO,
	NAME,
	AGE,
	SEX,
	TELE,
	ADDR,
};

struct PeoInfo
{
	char name[MAX_NAME];
	int age;
	char sex[MAX_SEX];
	char tele[MAX_TELE];
	char addr[MAX_ADDR];
};

struct contact
{
	struct PeoInfo date[MAX];
	int size;
};

void Initcon(struct contact* ps);

void Addcontact(struct contact* ps);

void Showcontact(const struct contact* ps);

void Delcontact(struct contact* ps);

void Searchcontact(const struct contact* ps);

void Modifycontact(struct contact* ps);

 感谢阅读!!!

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

网络安全防御保护 Day5

今天的任务如下 要求一的解决方法&#xff1a; 前面这些都是在防火墙FW1上的配置。 首先创建电信的NAT策略 这里新建转换后的地址池 移动同理&#xff0c;不过地址池不一样 要求二的解决方法&#xff1a; 切换至服务器映射选项&#xff0c;点击新建&#xff0c;配置外网通过…

RK3568笔记十七:LVGL v8.2移植

若该文为原创文章&#xff0c;转载请注明原文出处。 本文介绍嵌入式轻量化图形库LVGL 8.2移植到Linux开发板ATK-RK3568上的步骤。 主要是参考大佬博客&#xff1a; LVGL v8.2移植到IMX6ULL开发板_lvgl移植到linux-CSDN博客 一、环境 1、平台&#xff1a;rk3568 2、开发板:…

每日五道java面试题之java基础篇(十)

目录: 第一题 JVM有哪些垃圾回收器&#xff1f;第二题 垃圾回收分为哪些阶段&#xff1f;第三题 线程的⽣命周期&#xff1f;线程有⼏种状态&#xff1f;第四题.ThreadLocal的底层原理第五题.并发、并⾏、串⾏之间的区别 第一题 JVM有哪些垃圾回收器&#xff1f; ● 新⽣代收集…

ChatGPT绘图指南:DALL.E3玩法大全(二)

在前一篇文章中&#xff0c;我们介绍了什么是 DALL.E3 模型&#xff0c; DALL.E3 有什么优势&#xff0c;使用DALL.E3 的两种方法&#xff0c;以及DALL.E3 绘图的基本规则&#xff0c; 感兴趣的朋友请前往查看: ChatGPT绘图指南&#xff1a;DALL.E3玩法大全(一). 接下来&#…

【医学图像分割 2024】BEFUnet

文章目录 【医学图像分割 2024】BEFUnet摘要1. 介绍2. 相关工作2.1 基于CNN的分割网络2.2 ViT2.3 用于医学图像分割的Transformer 3. 方法3.1 双支路编码器3.1.1 边缘编码器3.1.2 主体编码器 3.2 LCAF模块3.2.1 双级融合模块(DLF) 3.3 损失函数3.3.1 边缘监督损失3.3.2 整体边缘…

GET 和 POST 方法有什么区别?

1.概述 当客户端通过 Web 与服务器通信时&#xff0c;此过程由超文本传输​​协议 ( HTTP) 启用。HTTP 是客户端和服务器之间的请求-响应协议。 GET 和 POST 方法是两种最常见的HTTP 请求方法。它们用于检索数据或将数据发送到服务器。它们是客户端-服务器模型的组成部分&…

云计算基础-存储基础

存储概念 什么是存储&#xff1a; 存储就是根据不同的应用程序环境&#xff0c;通过采取合理、安全、有效的方式将数据保存到某些介质上&#xff0c;并能保证有效的访问&#xff0c;存储的本质是记录信息的载体。 存储的特性&#xff1a; 数据临时或长期驻留的物理介质需要保…

EasyRecovery2024功能强大的电脑数据恢复软件

EasyRecovery是一款功能强大的数据恢复软件&#xff0c;支持从各种存储介质中恢复丢失或删除的文件。以下是EasyRecovery的下载教程、功能介绍以及最新版本简介&#xff1a; EasyRecovery支持多种操作系统版本。对于Windows系统&#xff0c;它支持Windows XP、Windows Vista、W…

linux系统zabbix监控分布式监控的部署

分布式监控 服务器安装分布式监控安装工具安装mysql导入数据结构配置proxy端浏览器配置 zabbix server端监控到大量zabbix agent端&#xff0c;这样会使zabbix server端压力过大&#xff0c;使用zabbix proxy进行分布式监控 服务器安装分布式监控 安装工具 rpm -Uvh https://…

从MobileNetv1到MobileNetv3模型详解

简言 MobileNet系列包括V1、V2和V3&#xff0c;专注于轻量级神经网络。MobileNetV1采用深度可分离卷积&#xff0c;MobileNetV2引入倒残差模块&#xff0c;提高准确性。MobileNetV3引入更多设计元素&#xff0c;如可变形卷积和Squeeze-and-Excitation模块&#xff0c;平衡计算…

CSS的background 背景图片自动适应元素大小,实现img的默认效果 background-size:100% 100%;

CSS的background 背景图片自动适应元素大小,实现img的默认效果 background-size:100% 100%; 关键是background-size:100% 100%; background-size:100% 100%; background-size:100% 100%; background-size:contain; 保持纵横比, 容器部分可能空白background-size:cover; 保…

自动更改由VSCode调试器创建的默认launch.json文件

File -> Preference -> Settings 修改下面的部分

文生视频:Sora模型报告总结

作为世界模拟器的视频生成模型 我们探索视频数据生成模型的大规模训练。具体来说&#xff0c;我们在可变持续时间、分辨率和宽高比的视频和图像上联合训练文本条件扩散模型。我们利用对视频和图像潜在代码的时空补丁进行操作的变压器架构。我们最大的模型 Sora 能够生成一分钟…

AJAX——AJAX入门

1 什么是AJAX&#xff1f; Ajax&#xff08;Asynchronous JavaScript and XML&#xff09;是一种用于在Web应用程序中实现异步通信的技术。 简单点说&#xff0c;就是使用XMLHttpRequest对象与服务器通信。它可以使用JSON、XML、HTML和test文本等格式发送和接收数据。 AJAX最吸…

JavaWeb之Servlet接口

Servlet接口 什么是Servlet&#xff1f; Servlet是一种基于Java技术的Web组件&#xff0c;用于生成动态内容&#xff0c;由容器管理&#xff0c;是平台无关的Java类组成&#xff0c;并且由Java Web服务器加载执行&#xff0c;是Web容器的最基本组成单元 什么是Servlet容器&…

2.13日学习打卡----初学RocketMQ(四)

2.13日学习打卡 目录&#xff1a; 2.13日学习打卡一.RocketMQ之Java ClassDefaultMQProducer类DefaultMQPushConsumer类Message类MessageExt类 二.RocketMQ 消费幂消费过程幂等消费速度慢的处理方式 三.RocketMQ 集群服务集群特点单master模式多master模式多master多Slave模式-…

【研究生复试】计算机软件工程人工智能研究生复试——资料整理(速记版)——数据库

1、JAVA 2、计算机网络 3、计算机体系结构 4、数据库 5、计算机租场原理 6、软件工程 7、大数据 8、英文 自我介绍 4. 数据库 1. B树相对于B树的区别及优势 B树中有重复元素&#xff0c;B树没有重复元素B树种每个节点都存储了key和data&#xff0c;B树内节点去掉了其中指向数…

数学实验第三版(主编:李继成 赵小艳)课后练习答案(十一)(1)(2)(3)

目录 实验十一&#xff1a;非线性方程&#xff08;组&#xff09;求解 练习一 练习二 练习三 实验十一&#xff1a;非线性方程&#xff08;组&#xff09;求解 练习一 1.求莱昂纳多方程 的解 clc;clear; p[1,2,10,-20]; roots(p)ans -1.6844 3.4313i -1.6844 - 3.4313i…

数据结构与算法:二叉树(寻找最近公共祖先、寻找后继节点、序列化和反序列化、折纸问题的板子和相关力扣题目)

最近公共祖先 第一版&#xff08;前提&#xff1a;p和q默认存在于这棵树中&#xff09; 可以层序遍历每个节点时用个HashMap存储该结点和其直接父节点的信息。然后从p开始溯源&#xff0c;将所有的父节点都添加到一个HashSet集合里。然后从q开始溯源&#xff0c;每溯源一步看…

题目:3.神奇的数组(蓝桥OJ 3000)

问题描述&#xff1a; 解题思路&#xff1a; 官方&#xff1a; 我的总结&#xff1a; 利用双指针遍历每个区间并判断是否符合条件&#xff1a;若一个区间符合条件则该区间在其左端点不变的情况下的每一个子区间都符合条件&#xff0c;相反若一个区间内左端点固定情况下有一个以…
最新文章