通讯录的实现(顺序表版本)

news2024/11/19 6:31:43

我们知道通讯录是基于顺序表的前提下,要写好通讯录我们就要深入了解好顺序表。我们先来看看什么是顺序表。(注意今天代码量有点多,坚持一下)。冲啊!兄弟们!

顺序表的简单理解

对于顺序表,我们首先要知道的是:它不仅物理存储结构上是连续的,逻辑层次上也是连续的。它的本质是数组。它是在数组上的增删查改。这其实就是一个顺序表。

typedef int SLDataType;
typedef struct SeqList
{
	SLDataType* arr;
	int size;//有效个数
	int capacity;//数组空间大小
}SL;

而这个顺序表的大小其实取决于你给这个数组开辟多少内存空间。

那我们来看看一个完整功能的顺序表是怎么实现的。我们将顺序表所需要的函数的头文件写在SeqList.h头文件中,将函数的实现写在SeqList.c中

SeqList.h的头文件所需要的函数:

#pragma once
//所需要的头文件
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include"Contact.h"
//动态顺序表
typedef int SLDataType;
typedef struct SeqList
{
	SLDataType* arr;
	int size;//有效个数
	int capacity;//数组空间大小
}SL;

//顺序表的初始化
void SLInit(SL* ps);
//顺序表的销毁
void SLDestroy(SL* ps);
//尾插
void SLpushBack(SL* ps, SLDataType x);
//空间的申请
void SLcheck(SL* ps);
//头插
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);

各种函数的实现

初始化函数的实现

一个变量需要初始化,而顺序表也不例外。

//顺序表初始化
void SLInit(SL* ps)
{
	ps->arr = NULL;
	ps->size = ps->capacity = 0;
}

顺序表销毁函数的实现

利用动态内存函数开辟的空间,如果不使用了,我们就要将他们释放掉,也就是顺序表的销毁。

//顺序表的销毁
void SLDestroy(SL* ps)
{
	//注意这里要判断一下数组地址是否为NULL,否则释放空指针空间会出问题
	if (ps->arr)
	{
		free(ps->arr);
	}
	ps->arr = NULL;
	ps->size = ps->capacity = 0;
}

尾插函数的实现

在尾插之前,我们需要判断一下,顺序表里面的那个数组的内存够不够这个数据的插入,那么我们可以将这样一个功能封装成一个函数。

//尾插
void SLpushBack(SL* ps, SLDataType x)
{
	assert(ps);
	SLcheck(ps);
	ps->arr[ps->size++] = x;
}
//空间申请
void SLcheck(SL* ps)
{
	if (ps->capacity == ps->size)
	{
		int newcapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;
		SLDataType* tmp = (SLDataType*)realloc(ps->arr, newcapacity * sizeof(SLDataType));
		if (tmp == NULL)
		{
			perror("realloc");
			return;
		}
		ps->arr = tmp;
		ps->capacity = newcapacity;
	}
}

头插函数的实现

尾插需要判断一下数组内存是否够不够插入,那么头插也是如此。

//头插
void SLpushFront(SL* ps, SLDataType x)
{
	assert(ps);
	SLcheck(ps);
	for (int i = ps->size; i > 0; i--)
	{
		ps->arr[i] = ps->arr[i - 1];
		//arr[1]=arr[0]
	}
	ps->arr[0] = x;
	ps->size++;

尾删函数的实现

实现这个函数,需要注意的是只要我们不影响其它函数的使用,即使不让开辟的内存释放也行的通

//尾删
void SLpopBack(SL* ps)
{
	assert(ps);
	ps->size--;
}

头删函数的实现

void SLpopFront(SL* ps)
{
	assert(ps);
	for (int i = 0; i < ps->size - 1; i++)
	{
		ps->arr[i] = ps->arr[i + 1];
		//arr[size-2]=arr[size-1]
	}
	ps->size--;

指定位置插入函数的实现

//指定位置插入
void SLInsert(SL* ps, int pos, SLDataType x)
{
	assert(ps);
	assert(pos >= 0 && pos <= ps->size);
	SLcheck(ps);
	for (int i = ps->size; i > pos; i--)
	{
		ps->arr[i] = ps->arr[i - 1];
		//arr[pos+1]=arr[pos]
	}
	ps->arr[pos] = x;
	ps->size++;
}

指定位置删除函数的实现

//指定位置删除
void SLErase(SL* ps, int pos)
{
	assert(ps);
	assert(pos >= 0 && pos < ps->size);
	for (int i = pos; i < ps->size - 1; i++)
	{
		ps->arr[i] = ps->arr[i + 1];
		//arr[size-2]=arr[size-1]
	}
	ps->size--;
}

通讯录函数声明和定义

我们将通讯录要用到的函数声明放到Contact.h头文件中,将函数的实现放到Contact.c的源文件中。

Contact.h头文件的函数:

#pragma once
//联系人结构体
//姓名  性别  年龄  电话  地址
#define NAME_MAX 20
#define GENDER_MAX 10
#define AGE_MAX 10
#define TEL_MAX 10
#define ADDR_MAX 10
typedef struct perinfo
{
	char name[NAME_MAX];
	char gender[GENDER_MAX];
	int age;
	char tel[TEL_MAX];
	char addr[ADDR_MAX];
}perinfo;


typedef struct SeqList Contact;//前置声明

//通讯录的初始化
void ContactInit(Contact* con);
//通讯录的销毁
void ContactDetroy(Contact* con);
//通讯录添加数据
void ContactAdd(Contact* con);
//通讯录删除数据
void ContactDelete(Contact* con);
//通讯录的修改
void ContactModify(Contact* con);
//通讯录的查找
int ContactFind(Contact* con);
//展示通讯录数据
void ContactShow(Contact* con);

通讯录函数的实现

通讯录初始化函数的实现

注意由于我们通讯录是基于顺序表的,所以一些函数可以调用顺序表中的函数。

//通讯录的初始化
void ContactInit(Contact* con)
{
	//通讯录的初始化实际上是顺序表的初始化
	//而顺序表的初始化已经实现了
	SLInit(con);
}

通讯录销毁函数的实现

这里可以调用顺序表里面的销毁函数。

//通讯录的销毁
void ContactDetroy(Contact* con)
{
	SLDestroy(con);
}

通讯录添加数据函数的实现

//通讯录添加数据
void ContactAdd(Contact* con)
{
	perinfo 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 ContactFindname(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 ContactDelete(Contact* con)
{
	//删除的数据要先存在才能删除,否则删除不了
	//查找
	char name[NAME_MAX];
	printf("请输入你要删除的联系人姓名:\n");
	scanf("%s", name);
	int find = ContactFindname(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("%.6s    %.6s    %d   %.6s   %.6s\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 = ContactFindname(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");
}

通讯录查找函数的实现

//通讯录的查找
int ContactFind(Contact* con)
{
	char name[NAME_MAX];
	printf("请输入要查找人的姓名:\n");
	scanf("%s", name);
	int find = ContactFindname(con,name);
	if (find < 0)
	{
		printf("没有此联系人!\n");
		return;
	}
	printf("%s %s %s %s %s\n", "姓名", "性别", "年龄", "电话", "地址");
	printf("%.6s    %.6s    %d   %.6s   %.6s\n", con->arr[find].name
		, con->arr[find].gender, con->arr[find].age, con->arr[find].tel
		, con->arr[find].addr);
}

总代码

SeqList.h文件

#pragma once
//所需要的头文件
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include"Contact.h"
//动态顺序表
typedef perinfo SLDataType;
typedef struct SeqList
{
	SLDataType* arr;
	int size;//有效个数
	int capacity;//数组空间大小
}SL;

//顺序表的初始化
void SLInit(SL* ps);
//顺序表的销毁
void SLDestroy(SL* ps);
//尾插
void SLpushBack(SL* ps, SLDataType x);
//空间的申请
void SLcheck(SL* ps);
//头插
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);

SeqList.c文件

#define _CRT_SECURE_NO_WARNINGS 1
#include"SeqList.h"
//各个函数的实现

//顺序表初始化
void SLInit(SL* ps)
{
	ps->arr = NULL;
	ps->size = ps->capacity = 0;
}
//顺序表的销毁
void SLDestroy(SL* ps)
{
	//注意这里要判断一下数组地址是否为NULL,否则释放空指针空间会出问题
	if (ps->arr)
	{
		free(ps->arr);
	}
	ps->arr = NULL;
	ps->size = ps->capacity = 0;
}
//尾插
void SLpushBack(SL* ps, SLDataType x)
{
	assert(ps);
	SLcheck(ps);
	ps->arr[ps->size++] = x;
}
//空间申请
void SLcheck(SL* ps)
{
	if (ps->capacity == ps->size)
	{
		int newcapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;
		SLDataType* tmp = (SLDataType*)realloc(ps->arr, newcapacity * sizeof(SLDataType));
		if (tmp == NULL)
		{
			perror("realloc");
			return;
		}
		ps->arr = tmp;
		ps->capacity = newcapacity;
	}
}
//头插
void SLpushFront(SL* ps, SLDataType x)
{
	assert(ps);
	SLcheck(ps);
	for (int i = ps->size; i > 0; i--)
	{
		ps->arr[i] = ps->arr[i - 1];
		//arr[1]=arr[0]
	}
	ps->arr[0] = x;
	ps->size++;
}
//尾删
void SLpopBack(SL* ps)
{
	assert(ps);
	ps->size--;
}
//头删
void SLpopFront(SL* ps)
{
	assert(ps);
	for (int i = 0; i < ps->size - 1; i++)
	{
		ps->arr[i] = ps->arr[i + 1];
		//arr[size-2]=arr[size-1]
	}
	ps->size--;
}
//指定位置插入
void SLInsert(SL* ps, int pos, SLDataType x)
{
	assert(ps);
	assert(pos >= 0 && pos <= ps->size);
	SLcheck(ps);
	for (int i = ps->size; i > pos; i--)
	{
		ps->arr[i] = ps->arr[i - 1];
		//arr[pos+1]=arr[pos]
	}
	ps->arr[pos] = x;
	ps->size++;
}
//指定位置删除
void SLErase(SL* ps, int pos)
{
	assert(ps);
	assert(pos >= 0 && pos < ps->size);
	for (int i = pos; i < ps->size - 1; i++)
	{
		ps->arr[i] = ps->arr[i + 1];
		//arr[size-2]=arr[size-1]
	}
	ps->size--;
}

Contact.h文件

#pragma once
//联系人结构体
//姓名  性别  年龄  电话  地址
#define NAME_MAX 20
#define GENDER_MAX 10
#define AGE_MAX 10
#define TEL_MAX 10
#define ADDR_MAX 10
typedef struct perinfo
{
	char name[NAME_MAX];
	char gender[GENDER_MAX];
	int age;
	char tel[TEL_MAX];
	char addr[ADDR_MAX];
}perinfo;


typedef struct SeqList Contact;//前置声明

//通讯录的初始化
void ContactInit(Contact* con);
//通讯录的销毁
void ContactDetroy(Contact* con);
//通讯录添加数据
void ContactAdd(Contact* con);
//通讯录删除数据
void ContactDelete(Contact* con);
//通讯录的修改
void ContactModify(Contact* con);
//通讯录的查找
int ContactFind(Contact* con);
//展示通讯录数据
void ContactShow(Contact* con);

Contact.c文件

#define _CRT_SECURE_NO_WARNINGS 1
#include"SeqList.h"
//通讯录的初始化
void ContactInit(Contact* con)
{
	//通讯录的初始化实际上是顺序表的初始化
	//而顺序表的初始化已经实现了
	SLInit(con);
}
//通讯录的销毁
void ContactDetroy(Contact* con)
{
	SLDestroy(con);
}
//通讯录添加数据
void ContactAdd(Contact* con)
{
	perinfo 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 ContactFindname(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 ContactDelete(Contact* con)
{
	//删除的数据要先存在才能删除,否则删除不了
	//查找
	char name[NAME_MAX];
	printf("请输入你要删除的联系人姓名:\n");
	scanf("%s", name);
	int find = ContactFindname(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("%.6s    %.6s    %d   %.6s   %.6s\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 = ContactFindname(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");
}
//通讯录的查找
int ContactFind(Contact* con)
{
	char name[NAME_MAX];
	printf("请输入要查找人的姓名:\n");
	scanf("%s", name);
	int find = ContactFindname(con,name);
	if (find < 0)
	{
		printf("没有此联系人!\n");
		return;
	}
	printf("%s %s %s %s %s\n", "姓名", "性别", "年龄", "电话", "地址");
	printf("%.6s    %.6s    %d   %.6s   %.6s\n", con->arr[find].name
		, con->arr[find].gender, con->arr[find].age, con->arr[find].tel
		, con->arr[find].addr);
}

test_1.c文件

将通讯录各个函数封装一下,制成一个菜单。

#define _CRT_SECURE_NO_WARNINGS 1
#include"SeqList.h"
void menu()
{
	printf("******通讯录*****\n");
	printf("*****1.添加联系人   2.删除联系人******\n");
	printf("*****3.查找联系人   4.修改联系人******\n");
	printf("*****5.展示联系人   0.退出通讯录*****\n");
}
int main()
{
	int input;
	Contact con;
	ContactInit(&con);
	do
	{
		menu();
		printf("请选择你的操作:\n");
		scanf("%d", &input);
		switch (input)
		{
		case 1:ContactAdd(&con);
			break;
		case 2:ContactDelete(&con);
			break;
		case 3:ContactFind(&con);
			break;
		case 4:ContactModify(&con);
			break;
		case 5:ContactShow(&con);
			break;
		case 0:printf("退出通讯录....\n");
			break;
		default:printf("选项不合法,重新选择\n");
			break;
		}
	} while (input);
	ContactDetroy(&con);
	return 0;
}

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

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

相关文章

地球上的七大洲介绍

地球上的七大洲示意图&#xff1a; 1. 亚洲&#xff08;Asia&#xff09;&#xff1a;世界上最大的洲&#xff0c;面积约为44579000平方公里。亚洲地域辽阔&#xff0c;包括从北极圈到赤道的各种气候和地形。它拥有世界上最多的人口&#xff0c;也是世界上一些最古老文明的发源…

2024年腾讯云最新优惠活动及领券入口整理分享

随着云计算技术的快速发展&#xff0c;越来越多的企业和个人选择将业务部署在云端。腾讯云作为国内知名的云计算服务提供商&#xff0c;为用户提供了丰富的云产品和服务。为了帮助用户降低成本&#xff0c;腾讯云定期推出各种优惠活动。本文将为大家整理分享2024年腾讯云的最新…

1.MMD模型动作场景镜头的导入及视频导出

界面介绍 MIKUMIKUDANCE926版本 MMD的工具栏模型骨骼帧的窗口&#xff0c;在不同时间做不同动作&#xff0c;可以在这里打帧操作时间曲线操作窗口&#xff0c;控制模型两个动作之间的过渡模型操作窗口&#xff0c;导入模型选择模型相机操作&#xff0c;控制相机远近&#xf…

JS/TS笔记学习2

周末总得学点什么吧~ 奥利给! 设计模式: 事件订阅派发模式 简单说就是:事件调度中心,负责接收事件发布者的消息&#xff0c;并将这些消息分发给所有订阅了该事件的订阅者 为什么用它&#xff0c;在构建大型、复杂或交互性强的应用程序时&#xff0c;用该模式非常方便&#xff0…

至少需要[XXXXMB]内存才能安装(宝塔导入数据库提示)

①我的2g内存腾讯云服务器想安装mysql8.0 ②宝塔提示“至少需要[3700MB]内存才能安装” 将数据库部署到宝塔上的时候提示-----》至少需要[XXXXMB]内存才能安装&#xff0c;解决的方法其实也很简单。 首先&#xff0c;进入文件夹/www/server/panel/class&#xff0c;找到找到…

OpenSSH 安全漏洞(CVE-2023-51385) 升级v9.7

漏洞编号&#xff1a;OpenSSH 安全漏洞(CVE-2023-51385) openssh9.7文件获取 https://f.ws59.cn/f/dtv9atef3io 复制链接到浏览器打开 处理方式 ##注释掉的根据实际情况处理 #查询原openssh9.4p1是否有安装openssh-askpass&#xff0c;若有需先删除 rpm -qa | grep openss…

解决Xshell登录云服务器的免密码和云服务器生成子用户问题

Xshell登录云服务器的免密码问题 前言一、Xshell登录云服务器的免密码操作实践 二、centos创建用户创建用户实操删除用户更改用户密码直接删除子用户 前言 Xshell登录云服务器免密码问题的解决方案通常涉及使用SSH密钥对。用户生成一对密钥&#xff08;公钥和私钥&#xff09;…

PE程序底层结构与恶意代码插入与执行的研究

Windows PE程序底层结构分析 PE&#xff08;Portable Executable&#xff09;是一种Windows操作系统下可执行文件的标准格式 Windows PE程序结构和Linux的elf程序结构类似&#xff0c;首先一个名为simple64.exe程序里有一个头文件和一个段文件&#xff0c;头文件里主要存放的是…

【STL】priority_queue的底层原理及其实现

文章目录 priority_queue的介绍库中priority_queue的使用什么叫仿函数&#xff1f; 模拟实现prioprity_queue类 priority_queue的介绍 解释以上内容 priority_queue&#xff08;优先级队列&#xff09;跟stack、queue一样&#xff0c;都是一种容器适配器&#xff0c;根据严格的…

产生死锁的四个必要条件

产生死锁的四个必要条件 互斥使用: 一个资源每次只能被一个线程使用。这意味着如果一个线程已经获取了某个资源&#xff08;比如锁&#xff09;&#xff0c;那么其他线程就必须等待&#xff0c;直到该线程释放资源。 不可抢占: 已经获得资源的线程在释放资源之前&#xff0c;不…

[leetcode] all-nodes-distance-k-in-binary-tree 二叉树中所有距离为 K 的结点

. - 力扣&#xff08;LeetCode&#xff09; 给定一个二叉树&#xff08;具有根结点 root&#xff09;&#xff0c; 一个目标结点 target &#xff0c;和一个整数值 k 。 返回到目标结点 target 距离为 k 的所有结点的值的列表。 答案可以以 任何顺序 返回。 示例 1&#xff1a…

一文了解ERC404协议

一、ERC404基础讲解 1、什么是ERC404协议 ERC404协议是一种实验性的、混合的ERC20/ERC721实现的&#xff0c;具有原生流动性和碎片化的协议。即该协议可让NFT像代币一样进行拆分交易。是一个图币的互换协议。具有原生流动性和碎片化的协议。 这意味着通过 ERC404 协议&#xf…

键值数据库Redis——Windows环境下载安装+命令行基本操作+Java操纵Redis

文章目录 前言一、下载与安装&#xff08;Windows环境&#xff09;** 检查数据库连接状态 **** 查看Redis数据库信息 ** 二、Redis五种数据结构与基本操作获取所有的key——keys *清空所有的key——flushall2.1 字符串操作2.2 散列操作2.3 列表操作2.4 集合操作2.5 位图操作 三…

【Java EE】 IoC详解(Bean的存储)

文章目录 &#x1f38d;Controller&#xff08;控制器存储&#xff09;&#x1f338;如何从Spring容器中获取对象&#xff08;ApplicationContext&#xff09;&#x1f338;获取bean对象的其他方式&#xff08;BeanFactory&#xff09;&#x1f338;Bean 命名约定&#x1f338;…

Java调用http接口的几种方式(HttpURLConnection、OKHttp、HttpClient、RestTemplate)

Java作为后端语言是开发接口实现功能供客户端调用接口&#xff0c;这些客户端中最主要是本项目的前端&#xff1b;但有时候也需要Java请求其他的接口&#xff0c;比如需要长连接转短链接&#xff08;请求百度的一个接口可以实现&#xff09;、获取三方OSS签名、微信小程序签名、…

数据结构(六)----串

目录 1.串的定义 2.串的基本操作 3.串的存储结构 (1)串的定义 •顺序存储 •链式存储 (2)求串长 (3)求子串 (4)比较串的大小 (5)定位操作 4.字符串的模式匹配 (1)朴素模式匹配算法 (2)KMP算法 •求模式串中的next数组&#xff08;重点&#xff09; •练习&#…

第四百六十回

文章目录 1. 概念介绍2. 方法与细节2.1 获取方法2.2 使用细节 3. 示例代码4. 内容总结 我们在上一章回中介绍了"如何获取当前系统语言"相关的内容&#xff0c;本章回中将介绍如何获取时间戳.闲话休提&#xff0c;让我们一起Talk Flutter吧。 1. 概念介绍 我们在本章…

适配器模式:连接不兼容接口的桥梁

在软件开发中&#xff0c;适配器模式是一种结构型设计模式&#xff0c;它允许不兼容的接口之间进行交互&#xff0c;从而使它们能够一起工作。这个模式经常用于系统升级或集成第三方库的时候&#xff0c;当现有的代码无法直接使用新系统或库提供的接口时&#xff0c;适配器可以…

基于Java+Vue的中国咖啡文化宣传网站(源码+文档+包运行)

一.系统概述 本课题是根据咖啡文化宣传需要以及网络的优势建立的一个中国咖啡文化宣传网站&#xff0c;来实现中国咖啡文化宣传以及咖啡商品售卖的功能。 本中国咖啡文化宣传网站应用Java技术&#xff0c;MYSQL数据库存储数据&#xff0c;基于SSMVue框架开发。在网站的整个开发…

【QT入门】Qt自定义控件与样式设计之自定义QLineEdit实现搜索编辑框

往期回顾 【QT入门】Qt自定义控件与样式设计之qss的加载方式-CSDN博客 【QT入门】Qt自定义控件与样式设计之控件提升与自定义控件-CSDN博客 【QT入门】Qt自定义控件与样式设计之鼠标相对、绝对位置、窗口位置、控件位置-CSDN博客 【QT入门】Qt自定义控件与样式设计之自定义QLin…