数据结构——通讯录项目

1.通讯录的介绍

顺序表是通讯录的底层结构。

通讯录是将顺序表的类型替换成结构体类型来储存用户数据,通过运用顺序表结构来实现的。

用户数据结构:

typedef struct PersonInfo
{
	char name[12];
	char sex[10];
	int age;
	char tel[11];
	char addr[100];
}PeoInfo;

2. 通讯录功能的实现

2.1 构建菜单

将通讯录的所有功能都一一列出来,让用户一目了然。

Contact.c:

void menu()
{
	printf("*******************************************\n");
	printf("******* 1.添加联系人    2.查找联系人 ******\n");
	printf("******* 1.修改联系人    2.删除联系人 ******\n");
	printf("******* 1.查看通讯录    0.退出通讯录 ******\n");
	printf("*******************************************\n");
}

测试结果如下:

 2.2 构建选择操作

Contact.c:

	int op = -1;
	do {
		menu();
		printf("请选择您的操作:\n");
		scanf("%d", &op);
		switch (op)
		{
		case 1:
			//添加联系人
			break;
		case 2:
			//查找联系人
			break;
		case 3:
			//修改联系人
			break;
		case 4:
			//删除联系人
			break;
		case 5:
			//查看通讯录
			break;
		case 0:
			//退出通讯录
			printf("通讯录退出中.....\n");
			break;
			
		}
	} while(op);

 测试结果如下:

 2.3 构建通讯录数据类型

Contact.c:

typedef struct PersonInfo
{
	char name[NAME_MAX];//使用宏便于后期修改代码
	char sex[SEX_MAX];
	int age;
	char tel[TEL_MAX];
	char addr[ADDR_MAX];
}PeoInfo;

2.4 通讯录的初始化和销毁

Contact.h:

//初始化通讯录
void InitContact(contact* con);//实际初始化的是顺序表
//销毁通讯录数据
void DestroyContact(contact* con);

Contact.c:

void InitContact(contact* con)
{
	SLInit(con);
}
void DestroyContact(contact* con)
{
	SLDestory(con);
}

2.5 增加联系人

Contact.h:

void AddContact(contact* con);

Contact.c:

void AddContact(contact* con)
{
	SLCheckCapacity(con);
	printf("请输入联系人姓名:\n");
	scanf("%s", con->arr[con->size].name);
	printf("请输入联系人性别:\n");
	scanf("%s", con->arr[con->size].sex);
	printf("请输入联系人年龄:\n");
	scanf("%d", &con->arr[con->size].age);
	printf("请输入联系人电话:\n");
	scanf("%s", con->arr[con->size].tel);
	printf("请输入联系人住址:\n");
	scanf("%s", con->arr[con->size].addr);
	con->size++;
}

测试结果如下:

2.6 展示联系人

Contact.h:

void ShowContact(contact* con);

Contact.c:

void ShowContact(contact* con) {
	printf("%-20s\t%-5s\t%-4s\t%-12s\t%-20s\n", "姓名", "性别", "年龄", "电话", "住址");
	for (int i = 0; i < con->size; i++)
	{
		printf("%s %s %d %s %s\n",
			con->arr[i].name,
			con->arr[i].sex,
			con->arr[i].age,
			con->arr[i].tel,
			con->arr[i].addr
		);
	}
}

测试结果如下:

2.7 查找联系人

Contact.h:

void FindContact(contact* con);

Contact.c:

//查找通讯录数据
int FindByName(contact* con, char name[])//根据需求设计查找的方式
{
	for (int i = 0; i < con->size; i++)
	{
		if (strcmp(con->arr[i].name, name) == 0)
		{
			return i;
		}
	}
	return -1;
}
void FindContact(contact* con)
{
	char name[NAME_MAX];
	printf("请输入要查找人的名字:\n");
	scanf("%s", name);
	int FindIndex = FindByName(con, name);
	if (FindIndex < 0)
	{
		printf("联系人不存在!\n");
		return;
	}
	printf(%-20s\t%-5s\t%-4s\t%-12s\t%-20s\n, "姓名", "性别", "年龄", "电话", "住址");
	printf(%-20s\t%-5s\t%-4s\t%-12s\t%-20s\n,
		con->arr[FindIndex].name,
		con->arr[FindIndex].sex,
		con->arr[FindIndex].age,
		con->arr[FindIndex].tel,
		con->arr[FindIndex].addr
	);
}

测试结果如下:

 2.8 删除联系人

 Contact.h:

void DelContact(contact* con);

Contact.c:

void DelContact(contact* con)
{
	//删除之前一定要查找
	printf("请输入要删除的联系人的姓名:\n");
	char name[NAME_MAX];
	scanf("%s", name);
	int ret = FindByName(con, name);
	//找不到,不能执行删除
	if (ret < 0)
	{
		printf("要删除的联系人不存在!\n");
		return;
	}
	//执行删除操作
	SLErase(con, ret);
}

测试结果如下:

2.9 修改联系人

Contact.h:

void ModifyContact(contact* con);

Contact.c:

void ModifyContact(contact* con)
{
	//修改之前进行查找
	char name[NAME_MAX];
	printf("请输入要修改联系人的姓名:\n");
	scanf("%s",name);
	int findIndex = FindByName(con, name);
	//没有找到,不能执行修改操作
	if (findIndex < 0)
	{
		printf("要修改的联系人不存在!\n");
		return;
	}
	//找到了,执行修改操作
	printf("请输入姓名:\n");
	scanf("%s", con->arr[findIndex].name);
	printf("请输入年龄:\n");
	scanf("%d", &con->arr[findIndex].age);
	printf("请输入性别:\n");
	scanf("%s", con->arr[findIndex].sex);
	printf("请输入电话:\n");
	scanf("%s", con->arr[findIndex].tel);
	printf("请输入地址:\n");
	scanf("%s", con->arr[findIndex].addr);
	printf("修改联系人成功!\n");
}
//找到了,执行修改操作
      

测试结果如下:

3. 通讯录功能优化

上面我们已经实现的通讯录的基本功能,但是我们会发现程序一旦结束,通讯录里储存的数据便会丢失。对于这种情况我们该如何解决呢?

答:将通讯录数据以二进制多大的方式储存到文件里

3.1 储存数据

Contact.h:

void SaveContact(contact* con)

Contact.c:

void SaveContact(contact* con) {
	FILE* pf = fopen("contact.txt", "wb");
	if (pf == NULL) {
		perror("fopen error!\n");
		return;
	}
	//将通讯录数据写⼊⽂件
	for (int i = 0; i < con->size; i++)
	{
		fwrite(&(con->arr[i]), sizeof(Info), 1, pf);
	}
	printf("通讯录数据保存成功!\n");
	fclose(pf);
}

测试结果如下:

3.2 读取数据

 Contact.h:

void LoadContact(contact* con);

Contact.c:

void LoadContact(contact* con) {
	FILE* pf = fopen("contact.txt", "rb");
	if (pf == NULL) {
		perror("fopen error!\n");
		return;
	}
	//循环读取⽂件数据
	Info info = { 0 };
	while (fread(&info, sizeof(Info), 1, pf))
	{
		SLCheckCapacity(con);
		con->arr[con->size] = info;
		con->size++;
	}
	//printf("%s %s\n", info.name, info.tel);
	printf("历史数据导入通讯录成功!\n");
	fclose(pf);

}

测试结果如下:

这样我们就不用担心数据丢失了!

4. 项目完整代码

SeqList.h:

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<string.h>
#include"Contact.h"
typedef Info SLDataType;
typedef struct SeqList
{
	SLDataType* arr;
	int capacity;
	int size;
}SL;
//初始化和打印
void SLInit(SL* ps);
void SLPrint(SL* ps);
//扩容
void SLCheckCapacity(SL* ps);
//头插和尾插
void SLPushBack(SL* ps, SLDataType x);
void SLPushFront(SL* ps, SLDataType x);
//头删和尾删
void SLPopBack(SL* ps);
void SLPopFront(SL* ps);
//在指定位置插入数据
void SLInsert(SL* ps, int pos, SLDataType x);
//在指定位置删除
void SLErase(SL* ps, int pos);
//查找数据
//int SLFind(SL* ps, SLDataType x);
//销毁
void SLDestory(SL* ps);

SeqList.c:

#define _CRT_SECURE_NO_WARNINGS 1
#include "SeqList.h"
void SLInit(SL* ps)
{
	ps->arr = NULL;
	ps->size = ps->capacity = 0;
}
//void SLPrint(SL* ps)
//{
//	for (int i = 0; i < ps->size; i++)
//	{
//		printf("%d ", ps->arr[i]);
//	}
//	printf("\n");
//}
//检查内存空间,扩容
void SLCheckCapacity(SL* ps)
{
	int newcapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;
	SLDataType* tmp = (SLDataType*)realloc(ps->arr, newcapacity * sizeof(SLDataType));
	if (tmp == NULL)
	{
		perror("realloc fall!");
		exit(1);
	}
	ps->arr = tmp;
	ps->capacity = newcapacity;
}
//尾插
void SLPushBack(SL* ps,SLDataType x)
{
	assert(ps);
	//空间不够,扩容
	SLCheckCapacity(ps);

	//空间足够,直接插入
	ps->arr[ps->size++] = x;
}
//头插
void SLPushFront(SL* ps, SLDataType x)
{
	assert(ps);
	//判断是否扩容
	SLCheckCapacity(ps);
	//旧数据往后挪动一位
	for (int i = ps->size; i > 0; i--)
	{
		ps->arr[i] = ps->arr[i - 1];
	}
	ps->arr[0] = x;
	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 SLInsert(SL* ps, int pos, SLDataType x)
{
	assert(ps && (pos>=0&&pos <= ps->size));
	//判断是否扩容
	SLCheckCapacity(ps);
	for (int 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 && (pos >= 0 && pos <= ps->size));
	//判断顺序表是否为空
	assert(ps->size);
	//不为空
	for (int i = pos; i < ps->size-1; i++)
	{
		ps->arr[i] = ps->arr[i + 1];

	}
	ps->size--;
}
//查找数据

//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;
//}
void SLDestory(SL* ps)
{
	assert(ps);
	if (ps->arr)
	{
		free(ps->arr);
	}
	ps->arr = NULL;
	ps->capacity = ps->size = 0;
}

Contact.h:

#pragma once
#include<stdio.h>
#define NAME_MAX 100
#define SEX_MAX 10
#define TEL_MAX 20
#define ADDR_MAX 100
//⽤户数据
typedef struct PersonInfo
{
	char name[NAME_MAX];
	char sex[SEX_MAX];
	int age;
	char tel[TEL_MAX];
	char addr[ADDR_MAX];
}Info;
//前置声明  防止头文件嵌套调用
typedef struct SeqList contact;

//初始化通讯录
void InitContact(contact* con);//实际初始化的是顺序表
//销毁通讯录数据
void DestroyContact(contact* con);
//添加通讯录数据
void AddContact(contact* con);
//展⽰通讯录数据
void ShowContact(contact* con);
//删除通讯录数据
void DelContact(contact* con);
//查找通讯录数据
void FindContact(contact* con);
//修改通讯录数据
void ModifyContact(contact* con);
//保存数据
void SaveContact(contact* con);
//读取数据
void LoadContact(contact* con);

Contact.c:

#include"SeqList.h"
void InitContact(contact* con)
{
	SLInit(con);
}
void DestroyContact(contact* con)
{
	SLDestory(con);
}
//添加联系人
void AddContact(contact* con)
{
	SLCheckCapacity(con);
	printf("请输入联系人姓名:\n");
	scanf("%s", con->arr[con->size].name);
	printf("请输入联系人性别:\n");
	scanf("%s", con->arr[con->size].sex);
	printf("请输入联系人年龄:\n");
	scanf("%d", &con->arr[con->size].age);
	printf("请输入联系人电话:\n");
	scanf("%s", con->arr[con->size].tel);
	printf("请输入联系人住址:\n");
	scanf("%s", con->arr[con->size].addr);
	con->size++;
}
//展⽰通讯录数据
void ShowContact(contact* con) {
	printf("%-20s\t%-5s\t%-4s\t%-12s\t%-20s\n", "姓名", "性别", "年龄", "电话", "住址");
	for (int i = 0; i < con->size; i++)
	{
		printf("%-20s\t%-5s\t%-4d\t%-12s\t%-20s\n",
			con->arr[i].name,
			con->arr[i].sex,
			con->arr[i].age,
			con->arr[i].tel,
			con->arr[i].addr
		);
	}
}
//查找通讯录数据
int FindByName(contact* con, char name[])//根据需求设计查找的方式
{
	for (int i = 0; i < con->size; i++)
	{
		if (strcmp(con->arr[i].name, name) == 0)
		{
			return i;
		}
	}
	return -1;
}
void FindContact(contact* con)
{
	char name[NAME_MAX];
	printf("请输入要查找人的名字:\n");
	scanf("%s", name);
	int FindIndex = FindByName(con, name);
	if (FindIndex < 0)
	{
		printf("联系人不存在!\n");
		return;
	}
	printf("%-20s\t%-5s\t%-4s\t%-12s\t%-20s\n", "姓名", "性别", "年龄", "电话", "住址");
	printf("%-20s\t%-5s\t%-4d\t%-12s\t%-20s\n",
		con->arr[FindIndex].name,
		con->arr[FindIndex].sex,
		con->arr[FindIndex].age,
		con->arr[FindIndex].tel,
		con->arr[FindIndex].addr
	);
}
//删除通讯录数据
void DelContact(contact* con)
{
	//删除之前一定要查找
	printf("请输入要删除的联系人的姓名:\n");
	char name[NAME_MAX];
	scanf("%s", name);
	int ret = FindByName(con, name);
	//找不到,不能执行删除
	if (ret < 0)
	{
		printf("要删除的联系人不存在!\n");
		return;
	}
	//执行删除操作
	SLErase(con, ret);
}
//修改通讯录数据
void ModifyContact(contact* con)
{
	//修改之前进行查找
	char name[NAME_MAX];
	printf("请输入要修改联系人的姓名:\n");
	scanf("%s",name);
	int findIndex = FindByName(con, name);
	//没有找到,不能执行修改操作
	if (findIndex < 0)
	{
		printf("要修改的联系人不存在!\n");
		return;
	}
	//找到了,执行修改操作
	printf("请输入姓名:\n");
	scanf("%s", con->arr[findIndex].name);
	printf("请输入年龄:\n");
	scanf("%d", &con->arr[findIndex].age);
	printf("请输入性别:\n");
	scanf("%s", con->arr[findIndex].sex);
	printf("请输入电话:\n");
	scanf("%s", con->arr[findIndex].tel);
	printf("请输入地址:\n");
	scanf("%s", con->arr[findIndex].addr);
	printf("修改联系人成功!\n");
}
//保存数据
void SaveContact(contact* con) {
	FILE* pf = fopen("contact.txt", "wb");
	if (pf == NULL) {
		perror("fopen error!\n");
		return;
	}
	//将通讯录数据写⼊⽂件
	for (int i = 0; i < con->size; i++)
	{
		fwrite(&(con->arr[i]), sizeof(Info), 1, pf);
	}
	printf("通讯录数据保存成功!\n");
	fclose(pf);
	pf = NULL;
}
//读取数据
void LoadContact(contact* con) {
	FILE* pf = fopen("contact.txt", "rb");
	if (pf == NULL) {
		perror("fopen error!\n");
		return;
	}
	//循环读取⽂件数据
	Info info = { 0 };
	while (fread(&info, sizeof(Info), 1, pf))
	{
		SLCheckCapacity(con);
		con->arr[con->size] = info;
		con->size++;
	}
	//printf("%s %s\n", info.name, info.tel);
	printf("历史数据导入通讯录成功!\n");
	fclose(pf);
	pf = NULL;
}

ConTest.c

#include"SeqList.h"
void menu()
{
	printf("*******************************************\n");
	printf("******* 1.添加联系人    2.查找联系人 ******\n");
	printf("******* 3.修改联系人    4.删除联系人 ******\n");
	printf("******* 5.查看通讯录    0.退出通讯录 ******\n");
	printf("*******************************************\n");
}
int main()
{
	int op = -1;
	contact con;
	//通讯录初始化
	InitContact(&con);
	LoadContact(&con);
	do {
		
		menu();
		printf("请选择您的操作:\n");
		scanf("%d", &op);
		switch (op)
		{
		case 1:
			//添加联系人
			AddContact(&con);
			break;
		case 2:
			//查找联系人
			FindContact(&con);
			break;
		case 3:
			//修改联系人
			ModifyContact(&con);
			break;
		case 4:
			//删除联系人
			DelContact(&con);
			printf("联系人删除成功!\n");
			break;
		case 5:
			//查看通讯录
			ShowContact(&con);
			break;
			break;
		case 0:
			//退出通讯录
			printf("通讯录退出中.....\n");
			break;
		}
	} while (op);
	SaveContact(&con);
	DestroyContact(&con);
	return 0;
}

 对于顺序表代码的实现在上一篇中有讲解,如果有的小伙伴有兴趣,可以去看一看。链接在下方:http://t.csdnimg.cn/wpM1t

本文为作者学习后的总结,如果有什么不恰当的地方,欢迎大佬指正!!! 

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

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

相关文章

【C++】C++的初步认识

&#x1f338;博主主页&#xff1a;釉色清风&#x1f338;文章专栏&#xff1a;C&#x1f338;今日语录&#xff1a;自律以修身&#xff0c;自省以观己。自学以长识&#xff0c;自处以蓄力。 &#x1f33b;Hi~大家好&#xff0c;这次文章是C的初步认识&#xff0c;包括从C语言到…

(黑马出品_高级篇_01)SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式

&#xff08;黑马出品_高级篇_01&#xff09;SpringCloudRabbitMQDockerRedis搜索分布式 微服务技术——保护 今日目标1.初识Sentinel1.1.雪崩问题及解决方案1.2.服务保护技术对比1.3.Sentinel介绍和安装1.3.1.初识Sentinel1.3.2.安装Sentinel 1.…

Mybatis Plus + Spring 分包配置 ClickHouse 和 Mysql 双数据源

目录 一、背景 二、各个配置文件总览&#xff08;文件位置因人而异&#xff09; 2.1 DataSourceConfig 2.2 MybatisClickHouseConfig &#xff08;ClickHouse 配置类&#xff09; 2.3 MybatisMysqlConfig&#xff08;Mysql 配置类&#xff09; 2.4 application.propertie…

Xterminal:未来的终端体验

✅作者简介&#xff1a;大家好&#xff0c;我是Leo&#xff0c;热爱Java后端开发者&#xff0c;一个想要与大家共同进步的男人&#x1f609;&#x1f609; &#x1f34e;个人主页&#xff1a;Leo的博客 &#x1f49e;当前专栏&#xff1a; 开发环境篇 ✨特色专栏&#xff1a; M…

Git版本控制工具简介

版本控制工具 分类 集中式版本控制工具 CVS、SVN、VSS 缺点&#xff1a;如果服务器一旦宕机&#xff0c;所有历史数据将会丢失 分布式版本控制工具 Git、Mercurial、Bazaar、Darcs...... 优势&#xff1a;本地即可进行版本控制&#xff0c;很好避免了单点故障 需要有一个远程…

软件设计师15--进程资源图

软件设计师15--进程资源图 考点1&#xff1a;进程资源图例题&#xff1a; 考点1&#xff1a;进程资源图 例题&#xff1a; 1、在如下所示的进程资源图中&#xff0c;D&#xff09;。 A、P1、P2、P3都是非阻塞节点&#xff0c;该图可以化简&#xff0c;所以是非死锁的 B、P1、…

基于SSH的物流配送管理系统的设计与实现

摘 要 当今社会&#xff0c;物流配送已成为影响经济发展的显著因素。而随着社会信息化发展&#xff0c;建立有效的物流配送管理体系不仅能够减少物流成本&#xff0c;更能够提升工作人员的工作效率与客户的满意度。而基于B/S架构的物流配送管理体系&#xff0c;不仅具有良好的…

ChatGPT提问技巧:受控生成提示

ChatGPT提问技巧&#xff1a;受控生成提示 受控生成提示是一种可以高度控制输出结果的文本生成技术。 具体做法是为模型提供一组特定的输入&#xff0c;如模板、特定词汇或一组约束&#xff0c;用于指导生成过程。 通过为模型提供一组可用于指导生成过程的特定输入&#xff…

Linux 动态库和静态库 【详解】

动静态库的基本原理 静态库&#xff08;.a&#xff09;&#xff1a;程序在编译链接的时候把库的代码链接到可执行文件中。程序运行的时候将不再需要静态库动态库&#xff08;.so&#xff09;&#xff1a;程序在运行的时候才去链接动态库的代码&#xff0c;多个程序共享使用库的…

解决ipconfig不是内部或外部命令,也不是可运行的程序或批处理文件

问题所示&#xff1a;ipconfig不是内部或外部命令&#xff0c;也不是可运行的程序或批处理文件。 解决办法如下: 1.右击此电脑&#xff0c;点击属性设置&#xff1a; 2.点击高级系统设置 3.点击进入环境变量 4.在系统变量中进行设置&#xff0c;双击PATH进行配置 5.点击新建&am…

yum安装mysql、数据库tab自动补全,快来浅了解下 ?

centos7上面没有mysql&#xff0c;它的数据库名字叫做mariadb [rootlocalhost ~]#yum install mariadb-server -y [rootlocalhost ~]#systemctl start mariadb.service [rootlocalhost ~]#systemctl stop firewalld [rootlocalhost ~]#setenforce 0 [rootlocalhost ~]#ss -na…

Kotlin:泛型

点击查看泛型中文文档 点击查看泛型英文文档 简介 与 Java 类似&#xff0c;Kotlin 中的类也可以有类型参数&#xff1a; class Box<T>(t: T) {var value t }一般来说&#xff0c;要创建这样类的实例&#xff0c;我们需要提供类型参数&#xff1a; val box: Box<…

SpringBoot项目中出现不同端口跨域问题,如何解决?

方法一&#xff1a;比较繁琐&#xff0c;适合少量Controller控制器类 方法二 &#xff1a;需要写一个全局的配置文件即可 在如图所示的common目录下新建一个CorsConfig的class文件 具体代码展示&#xff1a; import org.springframework.context.annotation.Bean; import o…

淘宝客必看:微信公众号如何快速接入抖音本地团购并提高CPS收益

抖音已经成为社交媒体新的流量高地&#xff0c;抖音团购完全复刻了美团的模式&#xff0c;外卖、到店、吃喝玩乐全覆盖。很多淘宝客一直在寻找通过微信公众号实现营销变现的有效途径&#xff1f;是否对于如何将抖音团购转变为自己的佣金收入感到困惑&#xff1f;微信公众号接入…

Eslint + Prettier 配置

setting.json {"eslint.autoFixOnSave": true, // 保存文件时自动修复可修复的问题"eslint.validate": [// 定义哪些文件类型应该由 ESLint 验证"javascript","javascriptreact","vue" // 如果你正在使用 Vue&#xff0c;确…

基于单片机的GPS定位信息显示系统

基于单片机的GPS定位信息显示系统 摘 要 在当今信息时代的发展中&#xff0c;GPS全球定位系统是一个重要的组成部分&#xff0c;其具有精度很高、应用广泛、性能强大的特点&#xff0c;因此在实际生活中GPS全球定位显示系统被广泛运用于各类领域当中。它也是至今为止最好的定…

HarmonyOS 发送系统通知 基础通知

harmonyos中 提供了 各种不同功能的通知 来满足我们不同的业务需求 本文呢 我们先来看 最基本的通知 它的场景和使用方式 最基本的 是 当应用被切入后台 而应用内部发生了一些变化 就可以用通知的方式 来提醒用户 就比如 我们微信 被切到了后台 而这时 别人发消息过来了 那么…

2014

1,写出计算Ack(m,n)的递归算法 #include<iostream> using namespace std; int A(int m,int n){if(m0){return n1;}else if(m>0&&n0){return A(m-1,1);}else{return A(m-1,A(m,n-1));} }int main(){int m,n;cout<<"please input two number"&l…

【深度学习笔记】7_7 AdaDelta算法

注&#xff1a;本文为《动手学深度学习》开源内容&#xff0c;部分标注了个人理解&#xff0c;仅为个人学习记录&#xff0c;无抄袭搬运意图 7.7 AdaDelta算法 除了RMSProp算法以外&#xff0c;另一个常用优化算法AdaDelta算法也针对AdaGrad算法在迭代后期可能较难找到有用解的…

分享一个国内可用的AIGC网站,PC/手机端通用|免费无限制,支持Claude3 Claude2

背景 AIGC作为一种基于人工智能技术的自然语言处理工具&#xff0c;近期的热度直接沸腾&#x1f30b;。 作为一个AI爱好者&#xff0c;翻遍了各大基于AIGC的网站&#xff0c;终于找到一个免费&#xff01;免登陆&#xff01;手机电脑通用&#xff01;国内可直接对话的AIGC&am…