学C的第三十一天【通讯录的实现】

news2024/11/18 16:23:13

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

相关代码gitee自取:C语言学习日记: 加油努力 (gitee.com)

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

接上期

学C的第三十天【自定义类型:结构体、枚举、联合】_高高的胖子的博客-CSDN博客

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

                     

通讯录需求:

             

实现一个通讯录

通讯录中存放保存人的信息

名字年龄性别

电话地址

             

        通讯录相关功能

  • 通讯录中可以存放100个人的信息
  • 增加联系人
  • 删除指定联系人
  • 修改指定联系人
  • 查找指定联系人
  • 显示所有联系人的信息
  • 排序功能

         

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

             

多文件实现通讯录

(1). contact.h文件 -- 相关函数和结构体类型的声明:

               

1 . 结构体 struct PeoInfo -- 存放通讯录联系人的信息:

                

使用 typedef 重命名结构体

struct PeoInfo 重命名PeoInfo

方便后续使用

              

图示:

              

              

2 . 结构体 struct contact -- 通讯录类型:

                

使用 typedef 重命名结构体, 

                     

创建通讯录信息结构体变量数组

                    

创建一个变量来记录当前通讯录data的人数

                      

图示:

                     

              

3 . 函数 InitContact() 的声明 -- 初始化通讯录类型变量

                

参数接收 -- 通讯录类型变量地址

返回类型 -- void

                   

图示:

                     

              

4 . 函数 AddContact() 的声明 -- 增加通讯录成员:

                

参数接收 -- 通讯录类型变量地址

返回类型 -- void

                 

图示:

                     

              

5 . 对常量使用进行优化 -- 设置 全局变量 和 枚举

                 

(一). 

设置 全局变量

contact.h 中,

定义全局变量 MAX 100 -- 设置通讯录最多人数,

其它通讯录信息也是同理

图示:

                

(二). 

设置 枚举

对测试中,用户输入的选项进行枚举

用对应的功能名字代表对应的选项

                 

在 contact.h 文件中设置好后,

在 test.c 文件中进行修改

图示:

                     

              

6 . 函数 ShowContact() 的声明 -- 打印通讯录所有成员信息:

                

参数接收 -- const Contact* pc

只是打印,不用修改所以设置为常量

           

返回类型 -- void

                  

图示:

                     

              

7 . 函数 FindByName() 的声明 -- 删除指定通讯录成员信息:

                

参数接收 -- 通讯录类型变量地址 要查找的名字字符串

返回类型 -- int,返回找到的元素下标 或 未找到情况的-1

         

注:

该函数只在 contact.c文件 中支持其它函数,
为了保密可以不在该文件声明

               

图示:

                     

              

8 . 函数 DelContact() 的声明 -- 删除指定通讯录成员信息:

                

参数接收 -- 通讯录类型变量地址

返回类型 -- void

                 

图示:

                     

                     

9 . 函数 SearchContact() 的声明 -- 查找指定通讯录成员信息:

                

参数接收 -- const Contact* pc

只是打印,不用修改所以设置为常量

           

返回类型 -- void

                   

图示:

                     

              

10 . 函数 ModifyContact() 的声明 -- 查找指定通讯录成员信息:

                

参数接收 -- 通讯录类型变量地址

返回类型 -- void

                 

图示:

                     

该文件对应代码:

#define _CRT_SECURE_NO_WARNINGS 1

//contact.h文件 -- 相关函数和类型的声明:

//包含头文件:
#include <string.h>
#include <assert.h>
#include <stdio.h>


//定义全局变量 MAX 100 -- 设置通讯录最多人数
#define MAX 100
//通讯录信息也是同理:
#define MAX_NAME 20
#define MAX_SEX 5
#define MAX_TELE 12
#define MAX_ADDR 30


//对测试中,用户输入的选项进行枚举,
//用对应的功能名字代表对应的选项:
enum OPTION
{
	//枚举中的内容默认0开始往后排:
	EXIT,	// 0 对应 退出
	ADD,	// 1 对应 增加
	DEL,	// 2 对应 删除
	SEARCH, // 3 对应 搜索
	MODIFY, // 4 对应 修改
	SHOW,	// 5 对应 显示所有
	SORT	// 6 对应 排序
};


//1.结构体 struct PeoInfo -- 存放保存人的信息:
//使用 typedef 重命名结构体,
typedef struct PeoInfo
{
	char name[MAX_NAME]; //名字
	int age; //年龄
	char sex[MAX_SEX]; //性别
	char tele[MAX_TELE]; //电话
	char addr[MAX_ADDR]; //地址
}PeoInfo;


//2.结构体 struct contact -- 通讯录类型:
//使用 typedef 重命名结构体,
typedef struct contact
{
	//创建通讯信息录结构体变量数组:
	PeoInfo data[MAX];

	//创建一个变量来记录当前通讯录data的人数:
	int sz;
}Contact;


//3.函数 InitContact() 的声明 -- 初始化通讯录类型变量
void InitContact(Contact* pc);

//4.函数 AddContact() 的声明 -- 增加通讯录成员:
void AddContact(Contact* pc);

//6.函数 ShowContact() 的声明 -- 打印通讯录所有成员信息:
void ShowContact(const Contact* pc);

//7.函数 FindByName() 的声明 -- 删除指定通讯录成员信息:
//该函数只在 contact.c文件 中支持其它函数,
//为了保密可以不在该文件声明
int FindByName(Contact* pc, char name[]);

//8.函数 DelContact() 的声明 -- 删除指定通讯录成员信息:
void DelContact(Contact* pc);

//9.函数 SearchContact() 的声明 -- 查找指定通讯录成员信息:
void SearchContact(const Contact* pc);

//10 . 函数 ModifyContact() 的声明 -- 查找指定通讯录成员信息:
void ModifyContact(Contact* pc);

                     

————————————————————————————————————————

                    

(2). contact.c文件 -- 自定义函数的实现:

              

1 . 函数 InitContact() -- 初始化通讯录类型变量

                

contact.h文件包含 <string.h> 头文件

再在 contact.c文件包含通讯录函数声明头文件:<contact.h>

              

使用 memset系统函数初始化data数组

参数1被设置的空间 -- data

参数2要设置的值 -- 0 (全部初始化为0)

参数3要设置的空间大小 -- sizeof(pc->data) ,直接计算出大小

                    

联系人个数 sz 初始化为0

                   

图示:

                     

              

2 . 函数 AddContact() -- 增加通讯录成员:

                

增加的前提还没放满

判断通讯录是否人数已满

                 

如果未满则开始添加信息

sz data数组 的下标对应的,
所以可以通过 sz 找到 data 的对应元素
通过对应元素找到对应元素的相应信息

如果对应的信息是数组,可以不加 取地址符&

使用 scanf()函数 将信息放进去

               

添加完一个联系人后,将指针移向下一个联系人位置

               

打印添加成功信息

                   

图示:

                     

              

3 . 函数 ShowContact() -- 打印通讯录所有成员信息:

                

打印列标题

再使用 for循环 循环打印信息

注意巧用 printf()函数

            

图示:

                     

              

4 . 函数 FindByName() -- 删除指定通讯录成员信息:

                

使用 for循环 循环在通讯录中查找该人坐标

使用 strcmp函数 进行判断名字是否存在

如果找到了则返回下标未找到则返回-1

                

图示:

                     

              

5 . 函数 DelContact() -- 删除指定通讯录成员信息:

                

判断通讯录是否为空为空没法删除则直接返回

                

不为空

输入接收删除的联系人名字

                 

调用 FindByName()函数 在通讯录中查找该人下标

               

未找到打印相应信息并返回

         

找到了删除该下标的联系人

            

删除后,将指针向前移一位

            

最后打印删除成功

                 

图示:

                     

              

6 . 函数 SearchContact() -- 查找指定通讯录成员信息:

                

输入接收查找的联系人名字

                 

调用 FindByName()函数 在通讯录中查找该人下标

               

未找到打印相应信息并返回

         

找到了打印该下标的联系人信息

               

图示:

                     

              

7 . 函数 ModifyContact() -- 查找指定通讯录成员信息:

                

输入接收修改的联系人名字

                 

调用 FindByName()函数 在通讯录中查找该人下标

               

未找到打印相应信息并返回

         

找到了修改该下标联系人信息

               
 图示:

                     

该文件对应代码:

#define _CRT_SECURE_NO_WARNINGS 1

//contact.c文件 -- 自定义函数的实现:

//包含头文件:
#include "contact.h"


//1.函数 InitContact() --初始化通讯录类型变量
void InitContact(Contact* pc)
{
	//断言:
	assert(pc);

	memset(pc->data, 0, sizeof(pc->data));
	/*使用 memset系统函数,初始化data数组。
	参数1:被设置的空间 -- data
	参数2:要设置的指-- 0 (全部初始化为0)
	参数3:要设置的空间大小-- sizeof(pc->data) ,
		   直接计算出大小*/

	//联系人个数初始化为0:
	pc->sz = 0;
}


//2.函数 AddContact() 的声明 -- 增加通讯录成员:
void AddContact(Contact* pc)
{
	//断言:
	assert(pc);

	//增加的前提是还没放满:
	if (pc->sz == MAX)
	{
		printf("通讯录已满,无法添加\n");
		//无法添加直接返回:
		return;
	}

	//没满则开始增加信息:
	// sz 和 data数组 的下标是对应的,
	// 所以可以通过 sz 找到 data 的对应元素,
	// 再通过对应元素找到对应元素的相应信息
	// 如果对应的信息是数组。可以不加&

	//名字:
	printf("请输入名字:>");
	//使用 scanf()函数 将信息放进去
	scanf("%s", pc->data[pc->sz].name);

	//年龄:
	printf("请输入年龄:>");
	//使用 scanf()函数 将信息放进去
	scanf("%d", &pc->data[pc->sz].age);

	//性别:
	printf("请输入性别:>");
	//使用 scanf()函数 将信息放进去
	scanf("%s", pc->data[pc->sz].sex);

	//电话:
	printf("请输入电话:>");
	//使用 scanf()函数 将信息放进去
	scanf("%s", pc->data[pc->sz].tele);

	//地址:
	printf("请输入地址:>");
	//使用 scanf()函数 将信息放进去
	scanf("%s", pc->data[pc->sz].addr);

	//添加完一个联系人后,将指针移向下一个联系人位置:
	pc->sz++;

	//打印添加成功信息:
	printf("成功添加联系人\n");
}


//3 . 函数 ShowContact() -- 打印通讯录所有成员信息:
void ShowContact(const Contact* pc)
{
	//断言:
	assert(pc);

	printf("\n");

	//打印列标题:
	printf("%-10s\t%-4s\t%-5s\t%-12s\t%-30s\n", 
		   "名字", "年龄", "性别", "电话", "地址");

	//使用 for循环 循环打印信息:
	int i = 0;
	for (i = 0; i < pc->sz; i++)
	{
		printf("%-10s\t%-4d\t%-5s\t%-12s\t%-30s\n", pc->data[i].name,
											   pc->data[i].age,
											   pc->data[i].sex,
											   pc->data[i].tele,
											   pc->data[i].addr
			  );
		// %20S:打印20个字符,这里名字是20个字符
		// \t: 使用制表符进行对齐
		// %4d:打印4个整型,这里是年龄
		// “-”号 :左对齐
	}


	printf("\n");

}


//4 . 函数 FindByName() -- 删除指定通讯录成员信息:
int FindByName(const Contact* pc, char name[])
{
	//遍历查找该人坐标:
	int i = 0;
	for (i = 0; i < pc->sz; i++)
	{
		if (strcmp(pc->data[i].name, name) == 0)
			//如果 找到了一个下标元素的name 和 要找的name 一样
		{
			return i; //返回此时找到的下标
		}
	}

	return -1; //未找到则返回-1
}


//5 . 函数 DelContact() --删除指定通讯录成员信息:
void DelContact(Contact* pc)
{
	//断言:
	assert(pc);

	//先判断通讯录是否为空:
	if (pc->sz == 0)
	{
		//为空就没法删除了,直接返回
		printf("通讯录为空,无法删除\n");
		return;
	}

	//创建存放要删除联系人名字的字符数组:
	char name[MAX_NAME] = { 0 };

	//输入并接收删除联系人名字:
	printf("请输入要删除的人名字:>");
	scanf("%s", name);

	//因为在通讯录中查找某人是多个功能所需要的,
	//所以可以将其封装成函数,再调用:
	int del = FindByName(pc, name);

	//如果del为-1,说明未找到:
	if (del == -1)
	{
		printf("要删除的人不存在\n");
		return; //直接返回
	}

	//如果找到了则删除坐标为del的联系人:
	int i = 0;
	for (i = del; i < pc->sz-1; i++)
		//从del下标开始,到倒数第二个元素
	{
		pc->data[i] = pc->data[i + 1];
		//把del后1个元素赋给del,循环覆盖掉del的元素
		//倒数第二个元素+1 为最后一个元素为止
	}

	//删除一个后,将pc指针向前移一位:
	pc->sz--;

	//打印提示:
	printf("成功删除该联系人\n");
}


//6 . 函数 SearchContact() -- 查找指定通讯录成员信息:
void SearchContact(const Contact* pc)
{
	//断言:
	assert(pc);

	//创建存放要查找的联系人名字的字符数组:
	char name[MAX_NAME] = { 0 };

	//输入并接收要查找联系人名字:
	printf("请输入要查找的联系人名字:>");
	scanf("%s", name);

	//使用 FindByName() 函数查找该人在通讯录中的下标:
	int pos = FindByName(pc, name);

	//如果del为-1,说明未找到:
	if (pos == -1)
	{
		printf("要查找的人不存在\n");
		return; //直接返回
	}
	else //找到了则打印该人信息: 
	{
		//打印列标题:
		printf("%-10s\t%-4s\t%-5s\t%-12s\t%-30s\n",
			"名字", "年龄", "性别", "电话", "地址");
		//打印对应信息:
		printf("%-10s\t%-4d\t%-5s\t%-12s\t%-30s\n", pc->data[pos].name,
													pc->data[pos].age,
													pc->data[pos].sex,
													pc->data[pos].tele,
													pc->data[pos].addr);
	}

}


//7 . 函数 ModifyContact() -- 查找指定通讯录成员信息:
void ModifyContact(Contact* pc)
{
	//断言:
	assert(pc);

	//创建存放要修改的联系人名字的字符数组:
	char name[MAX_NAME] = { 0 };

	//输入并接收要修改联系人名字:
	printf("请输入要修改的联系人名字:>");
	scanf("%s", name);

	//使用 FindByName() 函数查找该人在通讯录中的下标:
	int pos = FindByName(pc, name);

	//如果del为-1,说明未找到:
	if (pos == -1)
	{
		printf("要修改的人不存在\n");
		return; //直接返回
	}
	else //找到了则修改该人信息: 
	{
		//名字:
		printf("请输入名字:>");
		//使用 scanf()函数 将信息放进去
		scanf("%s", pc->data[pos].name);

		//年龄:
		printf("请输入年龄:>");
		//使用 scanf()函数 将信息放进去
		scanf("%d", &pc->data[pos].age);

		//性别:
		printf("请输入性别:>");
		//使用 scanf()函数 将信息放进去
		scanf("%s", pc->data[pos].sex);

		//电话:
		printf("请输入电话:>");
		//使用 scanf()函数 将信息放进去
		scanf("%s", pc->data[pos].tele);

		//地址:
		printf("请输入地址:>");
		//使用 scanf()函数 将信息放进去
		scanf("%s", pc->data[pos].addr);

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

                     

————————————————————————————————————————

                    

(3). test.c文件 -- 测试通讯录:

              

1 . 函数 void menu() -- 打印通讯录菜单:

                

告知使用者输入对应数字实现对应功能

               

图示:

                     

              

2 . 函数 void test() -- 完成通讯录测试:

                

(一). 

使用 do while 循环

                  

打印菜单

              

根据输入的选项判断是否需要再进行服务

可以使用 switch 语句进行筛选判断

图示:

             

(二).

包含<contact.h>头文件

通过结构体 struct contact (Contact),

创建通讯录类型变量 -- con

包含data数组,存放有效的通讯录数据

sz,记录存放数据的个数

                    

创建后还需要初始化

调用 函数InitContact() 进行初始化

参数接收通讯录类型变量的地址 -- &con

图示:

               

(三).

如果用户输入 1

则调用 函数AddContact()

增加联系人,

参数接收 &con 对通讯录进行对应操作

            

如果用户输入 2 ,

则调用 函数DelContact()

删除指定通讯录成员,

参数接收 &con 对通讯录进行对应操作

            

如果用户输入 3 ,

则调用 函数SearchContact()

查找指定联系人信息,

参数接收 &con 对通讯录进行对应操作

            

如果用户输入 4 ,

则调用 函数ModifyContact()

修改指定联系人信息,

参数接收 &con 对通讯录进行对应操作

            

如果用户输入 5 ,

则调用 函数ShowContact()

打印所有联系人信息,

参数接收 &con 对通讯录进行对应操作

            

如果用户输入 0

打印对应信息退出程序

               

如果用户 输入非法 

打印对应信息重新输入

              

图示:

                     

              

3 . 主函数

                

直接调用 test()测试函数即可

                

图示:

                     

该文件对应代码:

#define _CRT_SECURE_NO_WARNINGS 1

//test.c文件 -- 测试通讯录:

//包含<contact.h>头文件:
#include "contact.h"

//1 . 函数 void menu() -- 打印通讯录菜单:
void menu()
{
	// 选1:增加联系人		选2:删除联系人
	// 选3:搜索联系人		选4:修改联系人信息
	// 选5:显示所有联系人	选6:对联系人进行排序
	//				选0:退出通讯录
	printf("*****************************************************\n");
	printf("*****		1. add		2. del		*****\n");
	printf("*****		3. search	4. modify	*****\n");
	printf("*****		5. show		6. sort		*****\n");
	printf("*****			0. exit			*****\n");
	printf("*****************************************************\n");
}


//函数 void test() -- 完成通讯录测试:
void test()
{
	//创建通讯录类型变量:
	Contact con;
	//调用函数初始化通讯录类型变量:
	InitContact(&con);

	int input = 0;//接收输入的数据
	do
	{
		//调用菜单函数打印菜单:
		menu();

		//接收输入数据:
		printf("请选择:>");
		scanf("%d", &input);

		//使用switch语句进行筛选判断:
		switch (input)
		{
		case ADD:
			//如果用户输入1,
			//则调用AddContact()函数
			//添加联系人:
			AddContact(&con);
			//参数接收 &con ,对通讯录进行对应操作
			break;

		case DEL:
			//如果用户输入2,
			//则调用DelContact()函数
			//删除指定联系人:
			DelContact(&con);
			//参数接收 &con ,对通讯录进行对应操作
			break;

		case SEARCH:
			//如果用户输入3,
			//则调用SearchContact()函数
			//查找指定联系人:
			SearchContact(&con);
			//参数接收 &con ,对通讯录进行对应操作
			break;

		case MODIFY:
			//如果用户输入 4 ,
			//则调用ModifyContact()函数
			//修改指定联系人信息
			ModifyContact(&con);
			//参数接收 &con ,对通讯录进行对应操作
			break;

		case SHOW:
			//如果用户输入5,
			//则调用ShowContact()函数
			//打印所有联系人信息:
			ShowContact(&con);
			//参数接收 &con ,对通讯录进行对应操作
			break;

		case SORT:
			//待定
			break;

		case EXIT:
			//如果用户输入0,
			//打印对应信息并退出程序:
			printf("退出通讯录\n");
			break;

		default:
			//如果用户 输入非法,
			//打印对应信息并程序输入:
			printf("选择错误,重新选择\n");
			break;
		}

	} while (input);
	//只要输入数据不为0就继续进行
}

//主函数:
int main()
{
	//调用测试函数进行测试:
	test();

	return;
}

             

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

             

最终实现效果:

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

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

相关文章

【WebGL】初探WebGL,我了解到这些

WebGL&#xff08;Web图形库&#xff09;是一种强大的技术&#xff0c;允许您在Web浏览器中直接创建交互式的3D图形和动画。它利用现代图形硬件的能力来呈现令人惊叹的视觉效果&#xff0c;使其成为Web开发人员和计算机图形爱好者必备的技能。 WebGL基础知识 WebGL基于OpenGL …

1.3 eureka+ribbon,完成服务注册与调用,负载均衡源码追踪

本篇继先前发布的1.2 eureka注册中心&#xff0c;完成服务注册的内容。 目录 环境搭建 采用eurekaribbon的方式&#xff0c;对多个user服务发送请求&#xff0c;并实现负载均衡 负载均衡原理 负载均衡源码追踪 负载均衡策略 如何选择负载均衡策略&#xff1f; 饥饿加载…

数据结构07:查找[C++][线性查找]

图源&#xff1a;文心一言 考研笔记整理~&#x1f95d;&#x1f95d; 在数据结构和算法中&#xff0c;查找是一种常见的操作&#xff0c;它的目的是在一个数据集合中找到一个满足条件的元素。本文将介绍三种常用的查找方法&#xff0c;分别是顺序查找、折半查找和分块查找~&a…

61 # http 数据处理

node 中的核心模块 http 可以快速的创建一个 web 服务 const http require("http"); const url require("url");// req > request 客户端的所有信息 // res > respone 可以给客户端写入数据 const server http.createServer();server.on("r…

使用Spring Boot AOP实现日志记录

目录 介绍 1.1 什么是AOP 1.2 AOP体系与概念 AOP简单实现 2.1 新建一个SpringBoot项目&#xff0c;无需选择依赖 2.2 设置好本地Maven配置后&#xff0c;在pom.xml文件里添加添加maven依赖 2.3 创建一个业务类接口 2.4 在实体类实现接口业务 2.5 在单元测试运行结果 …

机器学习--课后作业--hw1

机器学习(课后作业–hw1) 本篇文章全文参考这篇blog 网上找了很多教程&#xff0c;这个是相对来说清楚的&#xff0c;代码可能是一模一样&#xff0c;只是进行了一些微调&#xff0c;但是一定要理解这个模型具体的处理方法&#xff0c;这个模型我认为最巧妙的它对于数据的处理…

【1.4】Java微服务:服务注册和调用(Eureka和Ribbon实现)

✅作者简介&#xff1a;大家好&#xff0c;我是 Meteors., 向往着更加简洁高效的代码写法与编程方式&#xff0c;持续分享Java技术内容。 &#x1f34e;个人主页&#xff1a;Meteors.的博客 &#x1f49e;当前专栏&#xff1a; 微服务 ✨特色专栏&#xff1a; 知识分享 &#x…

小研究 - JVM GC 对 IMS HSS 延迟分析(一)

用户归属服务器&#xff08;IMS HSS&#xff09;是下一代通信网&#xff08;NGN&#xff09;核心网络 IP 多媒体子系统&#xff08;IMS&#xff09;中的主要用户数据库。IMS HSS 中存储用户的配置文件&#xff0c;可执行用户的身份验证和授权&#xff0c;并提供对呼叫控制服务器…

ARTS Activity -- Using Java

About ARTS - Complete one ARTS per week: ● Algorithm: Do at least one LeetCode algorithm per week Review: Read and comment on at least one technical article in English ● Tips: Learn at least one technical trick ● Share: Share a technical article with op…

1.2 eureka注册中心,完成服务注册

目录 环境搭建 搭建eureka服务 导入eureka服务端依赖 编写启动类&#xff0c;添加EnableEurekaServer注解 编写eureka配置文件 启动服务,访问eureka Euraka服务注册 创建了两个子模块 在模块里导入rureka客户端依赖 编写eureka配置文件 添加Services 环境搭建 创建父…

08-向量的范数_范数与正则项的关系

⛳向量的范数 范数的公式是向量每个分量 绝对值 P 次方 再用幂函数计算 P 分之一&#xff0c;这里 P 肯定是整数 1&#xff0c;2&#xff0c;3…到正无穷都是可以的 向量的范数就是把向量变成一个标量&#xff0c;范数的表示就是两个竖线来表示&#xff0c;然后右下角写上 P&a…

LeetCode36.Valid-Sudoku<有效的数独>

题目&#xff1a; 思路&#xff1a; 这题并不难&#xff0c;它类似于N皇后问题。在N皇后问题中&#xff0c;行&#xff0c;列&#xff0c;对角线&#xff0c;写对角线&#xff0c;都不能出现连续的皇后。 本题类似&#xff0c;不过他是行&#xff0c;列&#xff0c;还有一个B…

【数据结构篇C++实现】- 图

友情链接&#xff1a;C/C系列系统学习目录 文章目录 &#x1f680;一、图的基本概念和术语1、有向图和无向图3、基本图和多重图4、完全图5、子图6、连通、连通图和连通分量7、强连通图、强连通分量8、生成树、生成森林9、顶点的度、入度和出度10、边的权和网11、稠密图、稀疏图…

【点云处理教程】00计算机视觉的Open3D简介

一、说明 Open3D 是一个开源库&#xff0c;使开发人员能够处理 3D 数据。它提供了一组用于 3D 数据处理、可视化和机器学习任务的工具。该库支持各种数据格式&#xff0c;例如 .ply、.obj、.stl 和 .xyz&#xff0c;并允许用户创建自定义数据结构并在程序中访问它们。 Open3D 广…

介绍壹牛NFT数字艺术藏品数藏源码

这个版本新增了不少功能&#xff0c;也修复了一些地方。 1.平台新增用户找回密码功能 2.平台新增短信注册&#xff08;实名制功能&#xff09; 3.平台新增主图后台添加功能 4.平台修复相关问题&#xff0c;系统高效运行 5、H5端与APP端在新UI完美适配 6、加入宝盒功能&…

04-导数判断凹(concave)凸(convex)性_导数用于泰勒展开

导数与函数凹凸性的关系 函数的二阶导数是和函数的凹凸性是有关系的&#xff0c;凹凸性怎么定义的&#xff1f; 先来做简单的回顾&#xff0c;更多的会在最优化方法里面给大家讲&#xff0c;这里先记住凸函数是向下凸的&#xff0c; 反正就是凹的&#xff0c;是否是凸函数可以…

Linux——平台设备及其驱动

目录 前言 一、平台设备 二、平台驱动 三、平台驱动简单实例 四、 电源管理 五、udev 和驱动的自动加载 六、使用平台设备的LED 驱动 七、自动创建设备节点 前言 要满足 Linux 设备模型&#xff0c;就必须有总线、设备和驱动。但是有的设备并没有对应的物理总线&#x…

【双评价笔记】农业指向之水资源评价

农业指向水资源单项评价是基于区域内及邻近地区气象站点长时间序列降水观测资料,通过空间插值得到多年平均降水量分布图层,降水量按照200,400,800,1200这个间断点分为好(很湿润),较好(湿润),一般(半湿润),较差(半干旱),差(干旱)5 个等级。 本次实验过程采用的评价分…

谷粒商城第七天-商品服务之分类管理下的分类的拖拽功能的实现

目录 一、总述 1.1 前端思路 1.2 后端思路 二、前端实现 2.1 判断是否能进行拖拽 2.2 收集受影响的节点&#xff0c;提交给服务器 三、后端实现 四、总结 一、总述 这个拖拽功能对于这种树形的列表&#xff0c;整体的搬迁是很方便的。但是其实现却并不是那么的简单。 …

CMU15-213 课程笔记 01-课程概览

知识点 这门课的目的&#xff1a;深入理解当你执行代码时&#xff0c;计算机在做什么 LLDB&#xff1a;基于 LLVM 的命令行调试器&#xff0c;类似 GBD 内存引用 Bug typedef struct {int a[2];double d; } struct_t;double fun(int i) {volatile struct_t s;s.d 3.14;s.a…