首页 > 其他分享 >顺序表的应用——通讯录的实现

顺序表的应用——通讯录的实现

时间:2024-07-04 09:01:24浏览次数:13  
标签:顺序 name Contact 通讯录 应用 printf find con

前言

本篇博客将接着上次顺序表的内容进行拓展应用,这次来为大家介绍通讯录的实现,它就是基于顺序表的结构完成的;如果你对此感兴趣,请看下面的内容;

1.顺序表的应用

我们前面学过,顺序表可以存放任意类型的元素,前面我们在顺序表中存放整型元素,浮点型元素等内置类型;今天,我们将在顺序表中存放结构体这种自定义类型的变量;生活中,大家都使用过手机的通讯录,通讯录中有联系人的各种信息,那么如果我们想创建一个通讯录,那么我们就需要把每个联系人的不同信息放到一个结构体中,并且将其存放起来,那么就需要用到顺序表这个数据结构了;

OK,上面说了通讯录的基本逻辑,下面开始进行代码实现;

首先,基于顺序表专题的代码,我们需要新创建一个通讯录的头文件和一个通讯录的实现文件;

 

这里我们就创建好了;下面我们需要在头文件中定义联系人数据结构,在这里,我们需要定义联系人的姓名、性别、年龄、电话、地址这五个信息,大家请看下面的代码;

#define NAME_MAX 20
#define GENDER_MAX 10
#define TEL_MAX 20
#define ADDR_MAX 100
typedef struct personInfo
{
	char name[NAME_MAX];
	int age;
	char gender[GENDER_MAX];
	char tel[TEL_MAX];
	char addr[ADDR_MAX];
}peoInfo;

这里大家可以看到,我们定义了我们需要的数据,并且规定了它们的大小;

下面,我们还需要在顺序表的头文件中。将数据类型进行替换;

typedef peoInfo SLDataType;

下面。我们要对通讯录实行初始化、销毁,增删查改等一系列操作;那么我们需要知道,对通讯录的操作实际上就是对顺序表进行操作;

那么这里我们就需要进行以下操作;

首先,我们要给顺序表改个名字,让它叫作通讯录;

​
typedef SL Contact;

​

这里我们就改好了,但是这里大家需要注意一个点,我们必须要在通讯录的头文件中进行前置声明,否则将找不到SL这个结构体;

1.1 通讯录的初始化

首先,我们需要在通讯录头文件中进行方法声明;

void ContactInit(Contact* con);

下面,我们要在通讯录的实现文件中去实现初始化的方法;这里大家注意,上面说了对通讯录的操作就是对顺序表的操作,那么我们只需要引用顺序表初始化的方法就可以实现对通讯录的初始化;这里大家就需要在通讯录的实现文件中包含两个头文件:"Contact.h"  "SeqList.h";然后我们就可以引用顺序表的初始化方法来对通讯录进行初始化了;

void ContactInit(Contact* con)
{
	SLInit(con);
}

初始化的代码很简单,直接引用顺序表中写好的初始化方法即可。

初始化完成后,我们需要进行测试,这个时候我们需要进行测试;

这里大家在测试的过程中打开调试窗口,监视一下con,你会发现,con实际上就是顺序表,这与我们前面所述一致,我们对通讯录操作实际上就是对顺序表进行操作。

1.2 通讯录的销毁

上面说完了初始化,下面来看通讯录的销毁,操作方法与上面类似;

首先还是要在通讯录的头文件中进行声明;

void ContactDestroy(Contact* con);

声明完后,我们要在“Contact.c”文件中进行方法实现;

void ContactDestroy(Contact* con)
{
	SLDestroy(con);
}

这里因为我们前面已经写过顺序表的销毁方法了,所以这里直接可以拿来用,代码比较简单。

实现完成后,我们要进行测试,继续在test.c文件中进行测试;

 测试的结果大家可以自行进行调试,这里不做赘述。

1.3 通讯录添加数据

 首先还是先在头文件中声明;

void ContactAdd(Contact* 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("%d", info.tel);
	printf("请输入要添加的联系人地址:\n");
	scanf("%d", info.addr);
	SLPushBack(con, info);
}

这里大家来看代码,我们要将用户输入的信息保存到通讯录中,所以我们需要先用通讯录来创建一个结构体变量,然后进行存储。这里要提醒大家一点,在输入年龄时,我们需要加上&操作符,儿其他的变量都是不需要的,因为大家可以看一开始我们对通讯录的定义,只有年龄是整型变量,其他的都是字符数组,我们知道数组名表示的就是首元素的地址,所以在这里我们输入的格式中不需要加&操作符,这一点希望大家注意一下;最后这里我以尾插为例来进行数据的插入。

下面来进行测试;

 

大家在测试的时候。可以进行调试,监视通讯录中的数据,如上图所示,我们可以发现已经将我们输入的联系人数据存入通讯录。

1.4 通讯录删除数据

上来我们还是先在“Contact.h”中声明方法;

void ContactDel(Contact* con);

下面来实现删除的方法,这里大家思考一下,我们想要删除数据,是不是先要有数据存在,我们才能进行删除,那么我们想要删除指定的信息,就必须得先进行查找;所以这里我们需要引进一个查找的函数,我们以查找姓名为例;

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;
	}
}

这里大家来看这个查找函数,我们用到了strcmp函数来判断两个字符串是否相等,如果返回值为0,那么证明我们找到了对应的姓名信息。

我们继续来实现删除的方法,大家看下面的代码;

 

void ContactDel(Contact* con)
{
	char name[NAME_MAX];
	scanf("%s", name);
	int find = FindByName(con, name);
	if (find < 0)
	{
		printf("要删除的联系人数据不存在\n");
		return;
	}
	SLErase(con, find);
	printf("删除成功\n");
}

这里我们要根据姓名来查找,所以直接创建一个字符数组即可,然后我们需要调用我们上面刚写的查找函数,如果返回值为负数,证明没有找到(返回的下标,下标不能为负数);如果找到了,这里我们要删除它,那么就需要用在顺序表中定义的方法“在指定位置删除数据”,这样我们就可以成功删除我们想删除的数据。

下面我们在test.c文件中测试一下通讯录的删除;

 大家发现,size变成了0,证明我们删除成功了。

1.5 通讯录的展示

 这里为大家介绍展示通讯录的方法;首先还是声明;

void ContactShow(Contact* con);

然后来进行方法的实现;

void ContactShow(Contact* con)
{
	printf("%s %s %s %s %s", "姓名", "性别", "年龄", "电话", "地址");
	for (int i = 0; i < con->size; i++)
	{
		printf("%s %s %d %s %s\n", con->arr[i].name,
			con->arr[i].gender,
			con->arr[i].age,
			con->arr[i].tel,
			con->arr[i].addr
		);
			
	}
}

这里我们要遍历通讯录,将通讯录中的信息打印出来;

下面我们来测试一下;

 

 

 大家可以看到,通讯录中的数据发生了变化,这里比调试看的更直观。

1.6 通讯录的修改

 继续来看通讯录的修改,一上来还是先进行声明;

void ContactModify(Contact* con);

下面再来实现修改的方法,这里大家要注意,要修改数据,前提要保证数据的存在性,所以这里的代码和上面的删除代码就有几分相似了;

这里大家会发现上半部分和删除的代码是一样的,下半部分我们只需要依次输入新的联系人数据即可。

​
void ContactModify(Contact* con)
{
	char name[NAME_MAX];
	printf("请输入要删除的联系人姓名\n");
	scanf("%s", name);
	int find = FindByName(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("%s", &con->arr[find].age);
	printf("请输入新的电话 \n");
	scanf("%s", con->arr[find].tel);
	printf("请输入新的地址 \n");
	scanf("%s", con->arr[find].addr);
	printf("修改成功\n");
}



​

下面来测试一下修改的代码;

 

大家可以看到。这里我们完成了修改。

1.7 通讯录的查找 

 还是在头文件中进行声明;

void ContactFind(Contact* con);

然后我们来实现查找方法;

void ContactFind(Contact* con)
{
	char name[NAME_MAX];
	printf("请输入要删除的联系人姓名\n");
	scanf("%s", name);
	int find = FindByName(con, name);
	if (find < 0)
	{
		printf("要查找的联系人数据不存在\n");
		return;
	}
	printf("%s %s %s %s %s\n", "姓名", "性别", "年龄", "电话", "地址");
	printf("%s %s %d %s %s\n", con->arr[find].name,
		con->arr[find].gender,
		con->arr[find].age,
		con->arr[find].tel,
		con->arr[find].addr
	);
}

接下来,我们来测试一下;

 

大家可以看到,在我们输入完信息后,我们可以查找到我们对应联系人的所有信息,这里我们的查找功能就成功实现了。

2. 通讯录的整体实现 

 上面已经为大家介绍完通讯录的所有操作了,下面我们要将其加工成一个像样的项目;

void meau()
{
	printf("************通讯录************\n");
	printf("**1.增加联系人  2.删除联系人**\n");
	printf("**3.修改联系人  4.查找联系人**\n");
	printf("**5.展示联系人  6.退出通讯录**\n");
	printf("******************************\n");
}
int main()
{
	int op = -1;
	Contact con;
	ContactInit(&con);
	do
	{
		meau();
		printf("请选择操作: \n");
		scanf("%d", &op);
		switch (op)
		{
		case 1:
			ContactAdd(&con);
			break;
		case 2:
			ContactDel(&con);
			break;
		case 3:
			ContactModify(&con);
			break;
		case 4:
			ContactFind(&con);
			break;
		case 5:
			ContactShow(&con);
			break;
		case 0:
			printf("通讯录退出\n");
			break;
		default :
			printf("输入错误,请选择正确的选项!\n");
			break;
		}
	} while (op != 0);
	ContactDestroy(&con);
	return 0;
}

这里我们增加了一个菜单来供用户选择,下面我们使用了do-while语句来实现循环的效果,还用到了switch语句来实现分支结构,经过这一系列操作,我们完善了通讯录项目。

下面为大家展示完整的代码;

首先,来展示头文件Contact.h 

#pragma once
#define _CRT_SECURE_NO_WARNINGS 1
#define NAME_MAX 20
#define GENDER_MAX 10
#define TEL_MAX 20
#define ADDR_MAX 100
typedef struct SeqList Contact;
typedef struct personInfo
{
	char name[NAME_MAX];
	int age;
	char gender[GENDER_MAX];
	char tel[TEL_MAX];
	char addr[ADDR_MAX];
}peoInfo;

void ContactInit(Contact* con);
void ContactDestroy(Contact* con);
void ContactAdd(Contact* con);
void ContactDel(Contact* con);
void ContactModify(Contact* con);
void ContactFind(Contact* con);
void ContactShow(Contact* con);

下面是通讯录的实现文件Contact.c

#include"Contact.h"
#include"Seqlist.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 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 ContactDel(Contact* con)
{
	char name[NAME_MAX];
	printf("请输入要删除的联系人姓名\n");
	scanf("%s", name);
	int find = FindByName(con, name);
	if (find < 0)
	{
		printf("要删除的联系人数据不存在\n");
		return;
	}
	SLErase(con, find);
	printf("删除成功! \n");
}
void ContactShow(Contact* con)
{
	printf("%s %s %s %s %s\n", "姓名", "性别", "年龄", "电话", "地址");
	for (int i = 0; i < con->size; i++)
	{
		printf("%s %s %d %s %s\n", con->arr[i].name,
			con->arr[i].gender,
			con->arr[i].age,
			con->arr[i].tel,
			con->arr[i].addr
		);
			
	}
}
void ContactModify(Contact* con)
{
	char name[NAME_MAX];
	printf("请输入要删除的联系人姓名\n");
	scanf("%s", name);
	int find = FindByName(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");
}
void ContactFind(Contact* con)
{
	char name[NAME_MAX];
	printf("请输入要查找的联系人姓名\n");
	scanf("%s", name);
	int find = FindByName(con, name);
	if (find < 0)
	{
		printf("要查找的联系人数据不存在\n");
		return;
	}
	printf("%s %s %s %s %s\n", "姓名", "性别", "年龄", "电话", "地址");
	printf("%s %s %d %s %s\n", con->arr[find].name,
		con->arr[find].gender,
		con->arr[find].age,
		con->arr[find].tel,
		con->arr[find].addr
	);
}

最后来看测试文件test.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"Seqlist.h"
void ContactTest01()
{
	Contact con;
	ContactInit(&con);
	ContactAdd(&con);
	ContactAdd(&con);
	ContactShow(&con);
	//ContactModify(&con);
	//ContactDel(&con);
	//ContactShow(&con);
	ContactFind(&con);
	ContactDestroy(&con);
}
int main()
{
	ContactTest01();
	return 0;
}

这里说明一下,通讯录是顺序表的应用,关于顺序表的相关方法,大家可以在我的另一篇博客《顺序表专题》中看到,这里就不再重复展示。

3. 总结

 本篇博客主要为大家介绍了顺序表这个数据结构的经典运用——通讯录,顺序表是数据结构的基础内容,希望大家理解并掌握顺序表的写法,同时通过通讯录来进一步加深对顺序表的理解。通讯录的本质就是顺序表,只不过套了一个的外壳,叫做了顺序表;最后,希望本篇博客可以为大家带来帮助,谢谢阅读!

 

 

标签:顺序,name,Contact,通讯录,应用,printf,find,con
From: https://blog.csdn.net/2302_81486993/article/details/139330487

相关文章

  • Vue技巧大揭秘:自定义指令的力量与应用
    引言自定义指令就像是给予开发者的一把魔法钥匙,它能够打开DOM操作的新世界,按我的理解就是把对DOM操作的逻辑进行封装全局注册与局部注册全局注册定义: 全局注册意味着自定义指令在Vue实例创建之前通过Vue.directive()方法注册,一旦注册,就可以在任意组件的模板中使用该指令。......
  • LLM应用:推荐系统
    随着信息的不断丰富,搜索和推荐成为了我们日常最长用到的两个功能,搜索是用户主动发起的信息查找需求,推荐则是平台根据用户标签/行为或用户query推荐给用户信息,用户是被动消费内容。比如在百度上搜索“周杰伦”时,搜索结果会给你推荐“大家都在搜”和“相关推荐”的query;再比如在......
  • SciTech-EECS-ADC/DAC: 源自Digikey的模数/数模转换文章:原理、类型、特点、应用、推
    ADC/DAC教程作者:PatSagsveen,投稿人:DigiKey,2017-09-13https://www.digikey.cn/zh/articles/adc-dac-tutorial如今的世界充满着各种数字信号和模拟信号。这些信号表现不同,但通常都被用来帮助实现更大的目标。ADC:想象你是负责控制HVAC装置的工程师。无论你打算使......
  • IISRESET 是用于重启 Microsoft Internet Information Services(IIS)的命令行工具。它通
    IISRESET命令起源于Microsoft开发的InternetInformationServices(IIS),这是一种用于Windows操作系统的强大的Web服务器软件。IIS早在WindowsNT3.51的时候就已经存在,而IISRESET命令则是作为管理和操作IIS服务的一部分而引入的。具体来说,IISRESET命令的主要功能是......
  • (必看图文)Hadoop集群安装及MapReduce应用(手把手详解版)
    前言    随着大数据时代的到来,处理和分析海量数据已成为企业和科研机构不可或缺的能力。Hadoop,作为开源的分布式计算平台,因其强大的数据处理能力和良好的可扩展性,成为大数据处理领域的佼佼者。本图文教程旨在帮助读者理解Hadoop集群的安装过程,并通过MapReduce应用实例,......
  • 【实际应用-第七篇 物联网 mqtt模拟实现单向通信 】
    文章目录概要发布方(模拟设备)引入pom回调MqttCallback发布的方法订阅方(模拟服务器)引入pom回调MqttCallback订阅的方法测试结果实际应用概要两个springboot项目,一个作为发布方,一个作为订阅方,模拟设备向服务器发送mqtt请求上报消息,示例使用的是......
  • Lumière:开创性的视频生成模型及其应用
     视频内容创造领域迎来了突破性进展,但视频生成模型由于运动引入的复杂性而面临更多挑战。这些挑战主要源自运动的引入所带来的复杂性。时间连贯性是视频生成中的关键要素,模型必须确保视频中的运动在时间上是连贯和平滑的,避免出现不自然的跳跃或断裂。空间关系的准确性也至关重......
  • 在Java中,Map 接口的实现(如 HashMap,LinkedHashMap,TreeMap 等)并不保证遍历 keySet() 或
    在Java中,Map接口的实现(如HashMap,LinkedHashMap,TreeMap等)并不保证遍历keySet()或entrySet()时的顺序。但是,某些特定的Map实现确实提供了特定的遍历顺序。1、HashMap:它基于哈希表实现,并不保证映射的顺序,特别是遍历顺序。因此,当你使用map.keySet()遍历HashMap时,结果可......
  • 关于自定义unordered_set\unordered_map中Hash和KeyEqual:函数对象和lambda表达式简单
    以unordered_set为例,首先在cppreference中查看其模板定义:可以看到Hash类默认是std::hash<Key,KeyEqual类似,本文将Hash以函数对象写出,将KeyEqual以lambda写出。classhashvec{ public: size_toperator()(constvector<int>&vec)const{ returnhash<int>()(vec[0])+hash......
  • 简单两步,让你的应用收录谷歌商店精品推荐
    大家好,我是牢鹅!当地时间6月27日谷歌已将粤语添加到谷歌翻译服务中,这是其有史以来最大规模扩展的一部分,借助生成人工智能(GenAI)技术,该服务可支持110种新语言。从上周四开始,谷歌工具应用程序和浏览器版本的用户可以在243种语言之间进行翻译,包括粤语。粤语是香港、澳门......