【顺序表的应用-通讯录的实现】
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
目录
前言
一、顺序表的应用
1. 基于动态顺序表实现通讯录
1、功能要求
2、代码实现
二、通讯录的代码实现
1.通讯录的底层结构(顺序表)
(1)思路展示
(2)底层代码实现(顺序表)
2.通讯录上层代码实现(通讯录结构)
(1).思路展示
(2).上层代码实现(通讯录)
3.通讯录代码运行展示
总结
前言
世上有两种耀眼的光芒,一种是正在升起的太阳,一种是正在努力学习编程的你!一个爱学编程的人。各位看官,我衷心的希望这篇博客能对你们有所帮助,同时也希望各位看官能对我的文章给与点评,希望我们能够携手共同促进进步,在编程的道路上越走越远!
提示:以下是本篇文章正文内容,下面案例可供参考
一、顺序表的应用
1. 基于动态顺序表实现通讯录
C语言基础要求:结构体、动态内存管理、顺序表、文件操作
1、功能要求
1)至少能够存储100个人的通讯信息
2)能够保存用户信息:名字、性别、年龄、电话、地址等
3)增加联系人信息
4)删除指定联系人
5)查找制定联系人
6)修改指定联系人
7)显示联系人信息
2、代码实现
【思考1】用静态顺序表和动态顺序表分别如何实现
【思考2】如何保证程序结束后,历史通讯录信息不会丢失
二、通讯录的代码实现
1.通讯录的底层结构(顺序表)
(1)思路展示
通讯录底层是顺序表来实现(相当于:通讯录 == 顺序表)
顺序表的底层结构是数组,对数组的封装,实现了常用的增删改查等接口
(2)底层代码实现(顺序表)
Seqlist.h(顺序表的头文件:目录)
#pragma once#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <stdbool.h>
#include "Contact.h"
//动态顺序表
//类型重命名(要加分号)
//如果我们要转换类型的话,就可以直接替换int
//typedef int SLDataType;
typedef struct ContactInfo SLDataType;//结构体的类型重命名要加struct
//我们把顺序表的数据类型改成联系人的结构体类型
typedef struct Seqlist
{SLDataType* a;//动态顺序表中底层结构中数组中的起始地址(a:指针变量,用来存放下面代码开辟空间的起始地址)int size; //顺序表中有效的数据个数 = 最后一个数据的下一个位置(因为位置的话,有下标0)int capacity; //顺序表中当前的空间大小
}SL;//对结构体类型初始化
//sl是结构体类型创建的变量
void SLInit(SL* ps);//销毁顺序表
void SLDestroy(SL* ps);//头部/尾部 插入或删除
void SLPushBack(SL* ps, SLDataType x);
//我们在顺序表中尾部插入一个SLDataType类型的数据x
void SLPushFront(SL* ps, SLDataType x);//头部插入void SLPopBack(SL* ps);//尾部删除
void SLPopFront(SL* ps);//头部删除//打印数据
void SLprint(SL* ps);//当把顺序表都初始化为0,而没有尾插和头插的话,就直接进行尾删,代码会报错
//判断顺序表是否为空
bool SLIsEmpty(SL* ps);//在任意位置插入数据
//在指定的位置之前插入数据
void SLInsert(SL* ps, int pos, SLDataType x);
//删除指定位置的数据
void SLErase(SL* ps, int pos);//在数据表中查找数据
bool SLFind(SL* ps, SLDataType x);
Seqlist.c(顺序表的源文件:函数的具体实现)
#define _CRT_SECURE_NO_WARNINGS 1//接口:我们后续提供给其他用户使用的函数或方法
#include "Seplist.h"
void SLInit(SL* ps)
{ps->a = NULL;ps->size = ps->capacity = 0;
}//销毁顺序表
void SLDestroy(SL* ps)
{//动态内存开辟了空间才能free()释放if (ps->a != NULL)free(ps->a);ps->a = NULL;ps->size = ps->capacity = 0;
}//判断当前顺序表的空间是否足够
void SLCheckCapacity(SL* ps)
{if (ps->size == ps->capacity){//结构体变量指向的有效数据个数==顺序表当前空间的大小,就得扩容//realloc()函数的第二个参数:顺序表当前空间的大小 * 2倍 * SLDataType的类型//首先得判断一下顺序表中当前空间的大小是否为0,因为为0的话,0*任何数都是0int newcapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;SLDataType* tmp = (SLDataType*)realloc(ps->a, newcapacity * sizeof(SLDataType));if (tmp == NULL){perror("realloc");return;}ps->a = tmp;ps->capacity = newcapacity;//顺序表当前空间的大小赋值给capacity,一个空间大小是SLDataType类型的}
}//头部/尾部 插入或删除
void SLPushBack(SL* ps, SLDataType x)
{assert(ps != NULL);//1:空间足够,直接尾插//2:空间不够,扩容//直接调用扩容函数SLCheckCapacity(ps);//直接插入数据ps->a[ps->size] = x;ps->size++;
}
//头插
void SLPushFront(SL* ps, SLDataType x)
{assert(ps != NULL);//判断空间是否足够的函数//空间不够,扩容SLCheckCapacity(ps);//空间足够,历史数据向后移一位for (size_t i = ps->size; i > 0; i--){ps->a[i] = ps->a[i - 1];}ps->a[0] = x;//第0个位置直接插入xps->size++;//既要增加数据,也要增加空间
}void SLPopBack(SL* ps)//尾部删除
{assert(ps != NULL);assert(!SLIsEmpty(ps));//SLIsEmpty(ps):如果为真,就进入函数,那么顺序表就为空//SLIsEmpty(ps):为真,加!就为假,那么断言执行,否则就不执行ps->size--;
}
void SLPopFront(SL* ps)//头部删除
{assert(ps);assert(!SLIsEmpty(ps));//让后面的数据往前挪动一位for (size_t i = 0; i < ps->size - 1; i++){//如果数组下标为ps->size的话,就越界了//因为size为有效数据的个数 = 最后一个数据的下一个位置(有下标为0)ps->a[i] = ps->a[i + 1];}ps->size--;
}//打印数据
void SLprint(SL* ps)
{for (size_t i = 0; i < ps->size; i++){printf("%d ", ps->a[i]);}printf("\n");
}//判断顺序表是否为空
bool SLIsEmpty(SL* ps)
{assert(ps != NULL);return ps->size == 0;//如果当前没有一个有效的数据,就为空
}//在任意位置插入数据
//在指定的位置之前插入数据
void SLInsert(SL* ps, int pos, SLDataType x)
{//pos的位置对于计算机看来是下标的意思assert(ps);//不要忘了对pos加以限制assert(pos >= 0 && pos <= ps->size);//怕有人会在-100之类的位置插入数据//扩容SLCheckCapacity(ps);//把pos位置及以后的数据往后挪动一位//循环条件里的i的初始值是size还是size-1都是可以的,但不同的初始值对应不同的结束条件for (size_t i = ps->size; i > pos; i--){//最后一个进来的值是pos+1ps->a[i] = ps->a[i - 1];}ps->a[pos] = x;ps->size++;
}
//删除指定位置的数据
void SLErase(SL* ps, int pos)
{assert(ps);assert(!SLIsEmpty(ps));//要对pos进行限制assert(pos >= 0 && pos < ps->size);for (int i = pos; i < ps->size - 1; i++){//最后一次进来的数据是ps->size-2(ps->size的话,就越界了)ps->a[i] = ps->a[i + 1];//ps->a[size-2] = ps->a[size-1]}ps->size--;
}
test1.c(顺序表源文件:顺序表的测试)
#define _CRT_SECURE_NO_WARNINGS 1#include "seqlist.h"void SLtest()
{SL sl;//定义一个顺序表,sl就是没有初始化//SLInit(sl);//我们把sl传递给一个初始化的方法进行初始化SLInit(&sl);//我们想要把sl初始化的话,要把地址传过去,因为形参是实参的一份临时拷贝//顺序表的具体操作//尾插SLPushBack(&sl, 1);SLPushBack(&sl, 2);SLPushBack(&sl, 3);SLPushBack(&sl, 4);//1 2 3 4SLprint(&sl);//头插SLPushFront(&sl, 5);//5 1 2 3 4 SLPushFront(&sl, 6);//6 5 1 2 3 4SLPushFront(&sl, 7);//7 6 5 1 2 3 4SLprint(&sl);//尾删SLPopBack(&sl);SLprint(&sl);SLPopBack(&sl);SLprint(&sl);//销毁顺序表SLDestroy(&sl);
}
void SLtest02()
{SL sl;SLInit(&sl);SLPushBack(&sl, 1);SLPushBack(&sl, 2);SLPushBack(&sl, 3);SLPushBack(&sl, 4);SLprint(&sl);//头删SLPopFront(&sl);SLprint(&sl);SLPopFront(&sl);SLprint(&sl); SLPopFront(&sl);SLprint(&sl);//到这里顺序表已经没有数据了SLPopFront(&sl);SLprint(&sl);//在任意位置插入数据//在指定的位置之前插入数据SLInsert(&sl, sl.size, 11);SLprint(&sl);//删除指定位置的数据SLErase(&sl, 0);SLprint(&sl);//在数据表中查找数据bool Findret = SLFind(&sl, 3);if (Findret == 3){printf("找到了!\n");}else{printf("找不到!\n");}//销毁顺序表SLDestroy(&sl);
}int main()
{//测试顺序表是否被初始化SLtest();SLtest02();return 0;
}
2.通讯录上层代码实现(通讯录结构)
(1).思路展示
1:因为通讯录底层是顺序表来实现(相当于:通讯录 == 顺序表)
2:所以通讯录首先要创建保存联系人数据的结构体,通讯录的信息类型创建好后,我们可以一键替换到顺序表中,其次再定义通讯录所需的函数实现即可
3:基于前面,我们已经知道,通讯录是基于动态顺序表实现的,所以在实现通讯录功能函数时,只需要在通讯录上层代码的源文件中,加上顺序表的头文件就可以调运顺序表已经实现好的函数来实现通讯录了。
(2).上层代码实现(通讯录)
Contact.h(通讯录的头文件:创建并保存联系人信息的头文件来替换动态顺序表的数据类型,起通讯录所需函数的声明)
#pragma once//创建保存联系人数据的结构
#define NAME_MAX 100
#define SEX_MAX 10
#define TEL_MAX 15
#define ADDR_MAX 100
//通讯录的信息类型创建好后,我们可以一键替换到顺序表中
//通讯录联系人的信息
typedef struct ContactInfo
{char name[NAME_MAX];char sex[SEX_MAX];int age;char tel[TEL_MAX];//电话号码char addr[ADDR_MAX];
}CInfo;
//CInfo:是结构体类型重命名,但是只在Contact.h(本文件)内使用,出了文件,别的文件都不认识//通讯录底层是顺序表来实现(相当于:通讯录 == 顺序表)
//给顺序表起个新名字
typedef struct Seqlist contact;
//为什么Contact.h文件中不包含#include "Seqlist.h"的头文件呢?
//因为我们的Contact.h头文件只是用了"Seqlist.h"的头文件的表面内容,并没有具体使用函数以及一些这个头文件的数据 //通讯录的创建和销毁
void ContactInit(contact* pcon);
void ContactDestroy(contact* pcon);//添加联系人(我们可以从终端,也就是屏幕获取,用scanf()函数,所以可以不用传参数)
void ContactAdd(contact* pcon);
//删除联系人
void ContactDel(contact* pcon);
//修改联系人
void ContactModify(contact* pcon);
//查看(展示)通讯录
void ContactShow(contact* pcon);
//查找指定联系人
void ContactFind(contact* pcon);
contact.c(通讯录的源文件:实现通讯录所需的函数功能)
#define _CRT_SECURE_NO_WARNINGS 1
//通讯录的实现文件
#include "Contact.h"
#include "Seplist.h"//通讯录初始化
void ContactInit(contact* pcon)
{SLInit(pcon);}
//通讯录销毁
void ContactDestroy(contact* pcon)
{SLDestroy(pcon);
}//添加联系人(我们可以从终端,也就是屏幕获取,用scanf()函数,所以可以不用传参数)
void ContactAdd(contact* pcon)
{//接下来要获取的信息都是CInfo结构体里要求的数据CInfo info;//结构体创建变量,用变量来获取终端输入的信息printf("请输入联系人姓名:\n");scanf("%s", info.name);//把输入的名字存放到变量的name结构体成员里printf("请输入联系人的性别:\n");scanf("%s", info.sex);printf("请输入联系人的年龄:\n");scanf("%d", &info.age);printf("请输入联系人的电话:\n");scanf("%s", info.tel);printf("请输入联系人的住址:\n");scanf("%s", info.addr);//联系人数据都获取到了,并保存在结构体info中//往通讯录(顺序表)中插入数据SLPushBack(pcon, info);//尾插 1:通讯录结构体传过去,2:联系人结构体保存的数据传过去
}//查找这个联系人到底在不在
int FindByName(contact* pcon,char name[])
{for (int i = 0; i < pcon->size; i++){if (strcmp(pcon->a[i], name) == 0)return i;//返回的是通讯录中数组的下标}return -1;
}//删除联系人
void ContactDel(contact* pcon)
{//直接强制要求用户使用联系人姓名来查找printf("请输入要删除的用户名称:\n");char name[NAME_MAX];scanf("%s", name);int Findidex = FindByName(pcon, name);if (Findidex < 0){printf("要删除的联系人不存在!\n");return;//这个函数就到此位置了}//找到了,要删除findidex位置的数据SLErase(pcon, Findidex);
}
//修改联系人
void ContactModify(contact* pcon)
{printf("请输入要修改的联系人名称:\n");char name[NAME_MAX];scanf("%s", name);//获取到通讯录(顺序表)下标的位置int find = FindByName(pcon, name);if (find < 0){printf("要修改的用户名称不存在!\n");return;//结束当前的方法运行//exit(1);//直接就把程序退出了,是粗暴的行为}printf("请输入新的用户名称:\n");scanf("%s", pcon->a[find].name);printf("请输入新的用户性别:\n");scanf("%s", pcon->a[find].sex);printf("请输入新的用户年龄:\n");scanf("%d", &pcon->a[find].age);printf("请输入新的用户电话:\n");scanf("%s", pcon->a[find].tel);printf("请输入新的用户住址:\n");scanf("%s", pcon->a[find].addr);printf("修改成功!\n");}
//查看(展示)通讯录
void ContactShow(contact* pcon)
{//打印通讯录所有的数据//先打印表头文字printf("%s %s %s %s %s\n", "姓名", "性别", "年龄", "电话", "地址");for (int i = 0; i < pcon->size; i++){printf("%s %s %d %s %s\n",pcon->a[i].name,pcon->a[i].sex,pcon->a[i].age,pcon->a[i].tel,pcon->a[i].addr);}
}
//查找指定联系人
void ContactFind(contact* pcon)
{printf("请输入要查找的用户名称:\n");char name[NAME_MAX];scanf("%s", name);int find = FindByName(pcon, name);if (find < 0){printf("该联系人不存在!\n");return;}//存在的话,打印当前的联系人printf("%s %s %s %s %s\n", "姓名", "性别", "年龄", "电话", "地址");printf("%s %s %d %s %s",pcon->a[find].name,pcon->a[find].sex,pcon->a[find].age,pcon->a[find].tel,pcon->a[find].addr);
}
test.c(通讯录的头文件:用来测试程序运行)
#define _CRT_SECURE_NO_WARNINGS 1
#include "Seplist.h"
#include "Contact.h"//void contact01()
//{
// contact con;
// ContactInit(&con);
// //往通讯录中插入数据
// ContactAdd(&con);
// //ContactAdd(&con);
// //展示通讯录
// ContactShow(&con);
// //ContactDel(&con);
// //ContactShow(&con);
// //修改联系人
// ContactModify(&con);
// ContactShow(&con);
// //查找指定联系人
// ContactFind(&con);
//
// ContactDestroy(&con);
//}void menu()
{printf("**************** 通讯录 ******************\n");printf("**********1.添加联系人 2.删除联系人**********\n");printf("**********3.修改联系人 4.查找联系人**********\n");printf("**********5.查找通讯录 0.退 出 ***********\n");printf("***********************************************\n");
}
int main()
{int input = 0;//定义一个通讯录contact con;ContactInit(&con);do{menu();printf("请选择您的操作!\n");scanf("%d", &input);switch(input){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("goodbye~\n");break;default:printf("输入错误,请重新输入!\n");break;}} while (input != 0);ContactDestroy(&con);//contact01();return 0;
}
3.通讯录代码运行展示

总结
好了,本篇博客到这里就结束了,如果有更好的观点,请及时留言,我会认真观看并学习。
不积硅步,无以至千里;不积小流,无以成江海。
相关文章:
【顺序表的应用-通讯录的实现】
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 目录 前言 一、顺序表的应用 1. 基于动态顺序表实现通讯录 1、功能要求 2、代码实现 二、通讯录的代码实现 1.通讯录的底层结构(顺序表) (1)思路展示 (2)底层代码实现(顺序表…...
[Spring Cloud] Nacos 实战 + Aws云服务器
文章目录 前言一、拥有一台Aws Linux服务器1.1、选择Ubuntu版本Linux系统1.2、创建新密钥对1.3、网络设置1.4、配置成功,启动实例1.5、回到实例区域1.6、进入具体的实例1.7、设置安全组 二、在Mac上连接Aws云服务,并安装配置JDK112.1、解决离奇的错误2.2…...
SpringCloud微服务注册中心:Nacos介绍,微服务注册,Ribbon通信,Ribbon负载均衡,Nacos配置管理详细介绍
微服务注册中心 注册中心可以说是微服务架构中的”通讯录“,它记录了服务和服务地址的映射关系。在分布式架构中,服务会注册到这里,当服务需要调用其它服务时,就这里找到服务的地址,进行调用。 微服务注册中心 服务注…...
身份证号码校验
根据《新版外国人永久居留身份证适配性改造要点》,公司需要把代码中对身份证的校验进行优化 就文档内容可以看到需要优化的要点是: 新版永居证号码以 9 开头 受理地区代码出生日期顺序码校验码;(共18位) egÿ…...
ArcGIS如何处理并加载Excel中坐标数据?
做GIS行业的各位肯定免不了跟数据打交道,其中数据的处理说复杂也复杂,因为我们要花时间去做数据的转换及调整工作,那说简单也简单,因为我们有很多的工具可以使用,那么今天我就给大家带来处理Excel中的GIS数据中的其中一…...
C++标准模板(STL)- 类型支持 (类型修改,从给定类型移除 const 或/与 volatile 限定符,std::remove_cv)
类型特性 类型特性定义一个编译时基于模板的结构,以查询或修改类型的属性。 试图特化定义于 <type_traits> 头文件的模板导致未定义行为,除了 std::common_type 可依照其所描述特化。 定义于<type_traits>头文件的模板可以用不完整类型实例…...
nodejs搭建本地服务
前端开发时想自己有个本地服务如下操作直接上干货 1.在桌面上直接在powerShell 输入命令行 npm install -g express-generator 然后 npm install -g express 然后新建一个例如server的文件夹 在powerShell执行 express myStudy -e 端口号默认是3000 直接在地址栏输入 http://…...
如何看待Unity新收费模式?
Unity新收费模式的变化主要在于将收费重心从功能分级收费转变为资源使用量收费,这个改变已经引起了一定的争议和反响。以下是我个人的看法: 优点: 更公平的收费方式:新的收费模式将更加公平,用户只需按照实际使用的数…...
Excel数据可视化—波士顿矩阵图【四象限图】
EXCEL系列文章目录 Excel系列文章是本人亲身经历职场之后萌发的想法,为什么Excel覆盖如此之广,几乎每个公司、学校、家庭都在使用,但是它深藏的宝藏功能却很少被人使用,PQ、BI这些功能同样适用于数据分析;并且在一些需…...
【Java】智慧工地管理系统源代码,支持二次开发,SaaS模式
智慧工地系统围绕工程现场人、机、料、法、环及施工过程中质量、安全、进度、成本等各项数据满足工地多角色、多视角的有效监管,实现工程建设管理的降本增效。 一、行业现状 1、施工现场管理难:安全事故频发,人工巡检难度大,质量进度协同难等…...
Lstm+transformer的刀具磨损预测
视频讲解: 基于Lstm+transformer的刀具磨损预测实战_哔哩哔哩_bilibili 结果展示: 数据展示: 主要代码: # pip install openpyxl -i https://pypi.tuna.tsinghua.edu.cn/simple/ # pip install optuna -i https://pypi.tuna.tsinghua.edu.cn/simple/ import numpy as np…...
本机idea连接虚拟机中的Hbase
相关环境: 虚拟机:Centos7 hadoop版本:3.1.3 hbase版本:2.4.11 zookeeper版本:3.5.7 Java IDE:IDEA JDK:8 步骤 步骤一:在idea创建一个maven项目 步骤二:在虚拟机里找到core-site.x…...
.NET中的Object类学习3_MemberwiseClone方法
文章目录 一、前言二、Object.MemberwiseClone方法1 定义2 示例3 备注 三、总结 一、前言 按照MSDN文档的章节顺序来,本文应该是第五节。 但是学了上一节 Finalize之后,发现其内容对实际开发帮助不大。 所以这次跳过了前面的GetHashCode、GetType章节&a…...
鼎捷前端开发校招岗技术面面经(已过)
前言 鼎捷一共两面,一面针对技术,这篇博客记录下我认为有价值的问题。 有价值的提问 js类的继承的方式 es5,涉及到原型、原型链的继承; es6,类与对象,extends,super; 还问到Vue…...
Rockchip平台rk3588源码下载编译(基于Android13)
Rockchip平台rk3588源码下载编译(基于Android13) 源码下载 下载地址 repo init --repo-url https://gerrit.rock-chips.com:8443/repo-release/tools/repo -u https://gerrit.rock-chips.com:8443/Android_T/manifests.git -m Android13.xml服务器镜像下载 repo init --rep…...
RuntimeError: PyPI no longer supports ‘pip search‘ (or XML-RPC search).
RuntimeError: PyPI no longer supports ‘pip search’ (or XML-RPC search). 1. ERROR: XMLRPC request failed Deprecated Methods https://warehouse.pypa.io/api-reference/xml-rpc.html#deprecated-methods PyPI XMLRPC Search Disabled https://status.python.org/inc…...
21款奔驰GLS450升级23P驾驶辅助 提升安全出行
辅助驾驶越来越多的被大家所青睐!为了提升驾驶安全性和舒适便捷性奔驰改装原厂半自动驾驶23P辅助系统 23P智能辅助驾驶系统还是很有必要的,因为在跑高速的时候可以使用23P智能驾驶的自动保持车速,保持车距,车道自动居中行驶以及自…...
iOS越狱检测总结
文章目录 前言检测越狱文件私有目录检测检测越狱软件检测系统目录是否变为链接动态库检测环境变量检测系统调用检测指令集调用检测其他方式检测 前言 在之前的文章中,已经带大家一起制作了一个屏蔽越狱检测的Tweak。本文就和大家一起学习整理一下iOS系统中有哪些越…...
场景驱动的 AI 体验设计:如何让智能 IDE 赋能遗留系统重写
作为 AutoDev 的核心开发,我们不仅在不断丰富 AutoDev 的功能以满足不同公司的定制需求,还在与各种团队进行持续交流。在处理遗留系统时,我们发现程序员们日常工作中需要面对大量使用过时技术、基础设施混乱的系统。 在这个背景下,…...
【封装UI组件库系列】搭建项目及准备工作
封装UI组件库系列第一篇搭建项目 前言 🌟搭建项目 创建工程 基本结构 1.创建8个组件展示页面 2.配置路由文件router/index.js 3.页面布局 🌟总结 前言 在前端开发中,大家可能已经用过各种各样的UI组件库了,现在市面上热…...
Leetcode 3577. Count the Number of Computer Unlocking Permutations
Leetcode 3577. Count the Number of Computer Unlocking Permutations 1. 解题思路2. 代码实现 题目链接:3577. Count the Number of Computer Unlocking Permutations 1. 解题思路 这一题其实就是一个脑筋急转弯,要想要能够将所有的电脑解锁&#x…...
项目部署到Linux上时遇到的错误(Redis,MySQL,无法正确连接,地址占用问题)
Redis无法正确连接 在运行jar包时出现了这样的错误 查询得知问题核心在于Redis连接失败,具体原因是客户端发送了密码认证请求,但Redis服务器未设置密码 1.为Redis设置密码(匹配客户端配置) 步骤: 1).修…...
基于Java Swing的电子通讯录设计与实现:附系统托盘功能代码详解
JAVASQL电子通讯录带系统托盘 一、系统概述 本电子通讯录系统采用Java Swing开发桌面应用,结合SQLite数据库实现联系人管理功能,并集成系统托盘功能提升用户体验。系统支持联系人的增删改查、分组管理、搜索过滤等功能,同时可以最小化到系统…...
MySQL JOIN 表过多的优化思路
当 MySQL 查询涉及大量表 JOIN 时,性能会显著下降。以下是优化思路和简易实现方法: 一、核心优化思路 减少 JOIN 数量 数据冗余:添加必要的冗余字段(如订单表直接存储用户名)合并表:将频繁关联的小表合并成…...
BLEU评分:机器翻译质量评估的黄金标准
BLEU评分:机器翻译质量评估的黄金标准 1. 引言 在自然语言处理(NLP)领域,衡量一个机器翻译模型的性能至关重要。BLEU (Bilingual Evaluation Understudy) 作为一种自动化评估指标,自2002年由IBM的Kishore Papineni等人提出以来,…...
「全栈技术解析」推客小程序系统开发:从架构设计到裂变增长的完整解决方案
在移动互联网营销竞争白热化的当下,推客小程序系统凭借其裂变传播、精准营销等特性,成为企业抢占市场的利器。本文将深度解析推客小程序系统开发的核心技术与实现路径,助力开发者打造具有市场竞争力的营销工具。 一、系统核心功能架构&…...
Python网页自动化Selenium中文文档
1. 安装 1.1. 安装 Selenium Python bindings 提供了一个简单的API,让你使用Selenium WebDriver来编写功能/校验测试。 通过Selenium Python的API,你可以非常直观的使用Selenium WebDriver的所有功能。 Selenium Python bindings 使用非常简洁方便的A…...
LangChain 中的文档加载器(Loader)与文本切分器(Splitter)详解《二》
🧠 LangChain 中 TextSplitter 的使用详解:从基础到进阶(附代码) 一、前言 在处理大规模文本数据时,特别是在构建知识库或进行大模型训练与推理时,文本切分(Text Splitting) 是一个…...
【QT控件】显示类控件
目录 一、Label 二、LCD Number 三、ProgressBar 四、Calendar Widget QT专栏:QT_uyeonashi的博客-CSDN博客 一、Label QLabel 可以用来显示文本和图片. 核心属性如下 代码示例: 显示不同格式的文本 1) 在界面上创建三个 QLabel 尺寸放大一些. objectName 分别…...
docker容器互联
1.docker可以通过网路访问 2.docker允许映射容器内应用的服务端口到本地宿主主机 3.互联机制实现多个容器间通过容器名来快速访问 一 、端口映射实现容器访问 1.从外部访问容器应用 我们先把之前的删掉吧(如果不删的话,容器就提不起来,因…...
