【C语言进阶】一万字教你实现简易通讯录管理

news2024/11/18 10:44:59

目录

  • 一. 通讯录要实现的功能
      • 1.项目文件分配
      • 2.通讯录基本功能
    • 二.test.c的实现
        • 1.逻辑代码的实现
        • 2.通讯录联系人信息的创建
      • 三.contacts.c的实现
          • 1.初始化通讯录
          • 2.添加联系人信息
          • 3.显示通讯录信息
          • 3.删除指定联系人信息
          • 4.查找指定联系人
          • 5.修改指定联系人信息
          • 6.以名字年龄排序通讯录
          • 7.清理通讯录
        • 四.源码
            • 1.test.c
            • 2.contacts.c
            • 3.contacts.h

一. 通讯录要实现的功能

1.项目文件分配

我们知道在一个工程中,不可能将所有代码都写到一个文件下,而是根据不同的功能模块,分配到多个文件下,这样便于以后的维护升级。
所以通讯录中我分配了3个文件: test.c用来实现逻辑代码、测试程序, contacts.c用来实现代码逻辑中功能函数的编写,contacts.h用来声明函数和头文件和定义全局变量并且把test.c和contacts.c文件联系起来

2.通讯录基本功能

那么我们要在通讯录中实现哪些功能呢?大致如下:

  1. 😎添加联系人信息
  2. 😜 删除指定联系人信息
  3. 😊查找指定联系人信息
  4. 😄修改指定联系人信息
  5. 😃显示所有联系人信息
  6. 😁以名字年龄排序所有联系人
  7. 😮清空所有联系人
  8. 😯能存储1000个联系人的信息

二.test.c的实现

1.逻辑代码的实现

一开始我们需要在test.c测试文件下编写整体的逻辑代码,我希望进到通讯录可以有个菜单显示可执行的功能供我多次选择,代码如下:

#include "contacts.h"

void meau()
{
	printf("*******************************************\n");
	printf("***********  1.add        2.del ***********\n");
	printf("***********  3.find       4.rev ***********\n");
	printf("***********  5.show       6.sort***********\n");
	printf("***********  0.exit       7.pur ***********\n");
	printf("*******************************************\n");
}

int main()
{
	int input = 0;
	do
	{
		meau();
		printf("请选择:>");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			break;
		case 2:
			break;
		case 3:
			break;
		case 4:
			break;
		case 5:
			break;
		case 6:
			break;
		case 0:
			printf("退出通讯录\n");
			break;
		case 7:
			break;
		default:
			printf("选择错误,请重新选择\n");
			break;
		}
	} while (input);
	return 0;
}

2.通讯录联系人信息的创建

为了保存联系人的信息包括其姓名、年龄、性别、住址、电话,显然我们需要使用结构体来保存多个不同的数据,我们在contacts.h文件下定义便于在其他文件下使用:
使用define定义的变量便于我们以后修改通讯录参数信息

#define MAX_PEO 1000
#define MAX_name 20
#define MAX_sex 6
#define MAX_addrO 15
#define MAX_tele 13

typedef struct peoinf//存放个人的信息
{
	char name[MAX_name];
	int age;
	char sex[MAX_sex];
	char addr[MAX_addrO];
	char tele[MAX_tele];
}peo;

在通讯录中除了联系人的个人信息我还希望能知道联系人的个数,所以我在创建一个包括联系信息联系人个数的结构体作为通讯录结构体:

typedef struct Contacts//通讯录包括联系人信息和联系人个数
{
	peo data[MAX_PEO ];
	int sz;
}contacts;

三.contacts.c的实现

1.初始化通讯录

在让通讯录执行功能之前,我们应先初始化通讯录让其初值在我们的控制下,首先我们在测试文件下定义结构体变量,用于函数传参
测试文件下向函数传参,接着我们在.h文件下声明函数在.c文件下编写函数,不光是初始化函数,下文所有函数都是如此操作.

	contacts con;
	ini_con(&con);//初始化通讯录

功能函数的实现

//初始化通讯录
void ini_con(contacts* p)
{
	assert(p);
	p->sz = 0;
	memset(p->data, 0, sizeof(p->data));
}
2.添加联系人信息

我们在向通讯录添加信息应当先判断通讯录是否已满,如果还有空间则向结构体中写入信息:

//添加通讯录信息
void addcon(contacts* p)
{
	assert(p);
	if (MAX_PEO == p->sz)
	{
		printf("通讯录已满");
	}
	else
	{
		printf("请输入姓名:>");
		scanf("%s", p->data[p->sz].name);
		printf("请输入年龄:>");
		scanf("%d", &(p->data[p->sz].age));
		printf("请输入性别:>");
		scanf("%s", p->data[p->sz].sex);
		printf("请输入住址:>");
		scanf("%s", p->data[p->sz].addr);
		printf("请输入电话:>");
		scanf("%s", p->data[p->sz].tele);
		p->sz++;
	}
	return;//void类型函数不需要返回什么
}

上图中除年龄之外的结构体成员都是数组,所以不需要用取地址

3.显示通讯录信息

我们希望通讯录可以将现有的信息显示出来,实现显示功能:
需要注意的是:因为各组数据长度不一,我们应该预先设置字符长度并且左对齐,让显示界面比较整齐,在打印数据之前 先打印了表头,便于清晰的显示通讯录中的联系人信息。

//显示通讯录信息
void Showcon(const contacts* p)
{
	assert(p);
	printf("%-20s\t%-4s\t%-10s\t%-15s\t%-13s\n", "姓名","年龄","性别","住址","电话");
	for (int i = 0; i < p->sz;i++)
	{
		printf("%-20s\t%-4d\t%-10s\t%-15s\t%-13s\n", p->data[i].name
			, p->data[i].age
			, p->data[i].sex
			, p->data[i].addr
			, p->data[i].tele);
	}
}

我们简单的演示下已有的功能:
在这里插入图片描述

3.删除指定联系人信息

要删除指定联系人我们就需要在通讯录中找到他,我们可以使用strcmp比较结构体中存放的姓名与输入要删除名字的大小,当strcmp返回0时即找到了要删除的联系人。
因为在之后的修改查找等功能,都需要使用到strcmp查找联系人的功能,我们可以直接将strcmp比较姓名封装为一个函数find返回联系人所在的下标位置:

//封装查找函数
int find(const contacts* p, char name[20])
{
	int i = 0;
	for (i = 0; i < p->sz; i++)
	{
		if (0 == strcmp(p->data[i].name, name))
			return i;
	}
	return -1;
}
//删除通讯录信息
void delcon(contacts* p)
{
	assert(p);
	char name[20] = { 0 };
	printf("请输入要删除的联系人姓名:>");
	scanf("%s", name);
	//int flag = 0;
	int pos = 0;
	if (0 == p->sz)
	{
		printf("通讯录为空,无法删除\n");
	}
	else
	{
		 pos = find(p, name);
	}
	if (pos == -1)
	{
		printf("要删除的联系人不存在\n");
		return;	
	}
	//int j = 0;
	//for (j = pos; j < p->sz - 1; j++)
	//{
	//	p->data[j] = p->data[j + 1];
	//}
	memmove(&(p->data[pos]), &(p->data[pos + 1]), (sizeof(peo) * (p->sz - pos + 2)));
	p->sz--;
	printf("已删除\n");
}

删除联系人的方法有三种: 1. 遍历将后面的联系人向前覆盖缺点有性能的下降。2. memmove向前覆盖. 3.最后一个联系人的信息覆盖到要删除的联系人的位置,缺点通讯录顺序会发生改变。

4.查找指定联系人

想要查找指定联系人,可以通过名字搜索使用封装好的find函数,查找到了直接显示。

//查找
void findcon(const contacts* p)
{
	assert(p);
	char name[20] = { 0 };
	printf("请输入要查找的联系人姓名:>");
	scanf("%s", name);
	int pos=find(p, name);
	if (-1 == pos)
		printf("无此联系人\n");
	else
	{
		printf("%-20s\t%-4s\t%-10s\t%-15s\t%-13s\n", "姓名", "年龄", "性别", "住址", "电话");
		printf("%-20s\t%-4d\t%-10s\t%-15s\t%-13s\n", p->data[pos].name
			, p->data[pos].age
			, p->data[pos].sex
			, p->data[pos].addr
			, p->data[pos].tele);
	}
}
5.修改指定联系人信息

为了修改到指定联系人的信息,我们需要通过姓名查找到联系人,再重新录入此人信息:

//修改
void revcon(contacts* p)
{
	assert(p);
	char name[20] = { 0 };
	printf("请输入要修改的联系人姓名:>");
	scanf("%s", name);
	int pos = find(p, name);
	if (-1 == pos)
		printf("无此联系人\n");
	else
	{
		printf("请输入姓名:>");
		scanf("%s", p->data[pos].name);
		printf("请输入年龄:>");
		scanf("%d", &(p->data[pos].age));
		printf("请输入性别:>");
		scanf("%s", p->data[pos].sex);
		printf("请输入住址:>");
		scanf("%s", p->data[pos].addr);
		printf("请输入电话:>");
		scanf("%s", p->data[pos].tele);
	}
}
6.以名字年龄排序通讯录

想要排序通讯录可以通过两种方式:通过姓名的字典序或者年龄的大小,这只要使用之前学过得qsort即可完成:

int cmp_int(const void* p1, const void* p2)
{
	assert(p1 && p2);
	return *(int*)p1 - *(int*)p2;
}
int cmp_char(const void* p1, const void* p2)
{
	assert(p1 && p2);
	return strcmp((*(peo*)p1).name, (*(peo*)p2).name);
}
//排序
void sortcon(contacts* p)
{
	printf("*******************************\n");
	printf("******** 1.年龄 2.姓名 ********\n");
	printf("*******************************\n");
	int input = 0;
	scanf("%d", &input);
	if (1 == input)
	{
		qsort(&p->data->age, p->sz, sizeof(peo), cmp_int);
		Showcon(p);
	}
	else
	{
		qsort(&p->data->name, p->sz, sizeof(peo), cmp_char);
	    Showcon(p);
	}
	return;
}

我们分别演示一下结果如下
在这里插入图片描述

7.清理通讯录

当我们不想再使用目前的通讯录时,可以使用清除的功能,将通讯录所有信息归零;
:::

//清除
void purcon(contacts* p)
{
	assert(p);
	p->sz = 0;
	memset(p->data, 0, sizeof(p->data));
}

四.源码

1.test.c
#define _CRT_SECURE_NO_WARNINGS 1

#include "contacts.h"

void meau()
{
	printf("*******************************************\n");
	printf("***********  1.add        2.del ***********\n");
	printf("***********  3.find       4.rev ***********\n");
	printf("***********  5.show       6.sort***********\n");
	printf("***********  0.exit       7.pur ***********\n");
	printf("*******************************************\n");
}

int main()
{
	contacts con;
	ini_con(&con);//初始化通讯录
	int input = 0;
	do
	{
		meau();
		printf("请选择:>");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			addcon(&con);
			break;
		case 2:
			delcon(&con);
			break;
		case 3:
			findcon(&con);
			break;
		case 4:
			revcon(&con);
			break;
		case 5:
			Showcon(&con);
			break;
		case 6:
			sortcon(&con);
			break;
		case 0:
			printf("退出通讯录\n");
			break;
		case 7:
			purcon(&con);
			break;
		default:
			printf("选择错误,请重新选择\n");
			break;
		}
	} while (input);
	return 0;
}
2.contacts.c
#define _CRT_SECURE_NO_WARNINGS 1

#include "contacts.h"

//初始化通讯录
void ini_con(contacts* p)
{
	assert(p);
	p->sz = 0;
	memset(p->data, 0, sizeof(p->data));
}
//封装查找函数
int find(const contacts* p, char name[20])
{
	int i = 0;
	for (i = 0; i < p->sz; i++)
	{
		if (0 == strcmp(p->data[i].name, name))
			return i;
	}
	return -1;
}
//添加通讯录信息
void addcon(contacts* p)
{
	assert(p);
	if (MAX_PEO == p->sz)
	{
		printf("通讯录已满");
	}
	else
	{
		printf("请输入姓名:>");
		scanf("%s", p->data[p->sz].name);
		printf("请输入年龄:>");
		scanf("%d", &(p->data[p->sz].age));
		printf("请输入性别:>");
		scanf("%s", p->data[p->sz].sex);
		printf("请输入住址:>");
		scanf("%s", p->data[p->sz].addr);
		printf("请输入电话:>");
		scanf("%s", p->data[p->sz].tele);
		p->sz++;
	}
	return;//void类型函数不需要返回什么
	
}

//显示通讯录信息
void Showcon(const contacts* p)
{
	assert(p);
	printf("%-20s\t%-4s\t%-10s\t%-15s\t%-13s\n", "姓名","年龄","性别","住址","电话");
	for (int i = 0; i < p->sz;i++)
	{
		printf("%-20s\t%-4d\t%-10s\t%-15s\t%-13s\n", p->data[i].name
			, p->data[i].age
			, p->data[i].sex
			, p->data[i].addr
			, p->data[i].tele);
	}
}

//删除通讯录信息
void delcon(contacts* p)
{
	assert(p);
	char name[20] = { 0 };
	printf("请输入要删除的联系人姓名:>");
	scanf("%s", name);
	//int flag = 0;
	int pos = 0;
	if (0 == p->sz)
	{
		printf("通讯录为空,无法删除\n");
	}
	else
	{
		 pos = find(p, name);
	}
	if (pos == -1)
	{
		printf("要删除的联系人不存在\n");
		return;	
	}
	//int j = 0;
	//for (j = pos; j < p->sz - 1; j++)
	//{
	//	p->data[j] = p->data[j + 1];
	//}
	memmove(&(p->data[pos]), &(p->data[pos + 1]), (sizeof(peo) * (p->sz - pos + 2)));
	p->sz--;

	printf("已删除\n");
}

//查找
void findcon(const contacts* p)
{
	assert(p);
	char name[20] = { 0 };
	printf("请输入要查找的联系人姓名:>");
	scanf("%s", name);
	int pos=find(p, name);
	if (-1 == pos)
		printf("无此联系人\n");
	else
	{
		printf("%-20s\t%-4s\t%-10s\t%-15s\t%-13s\n", "姓名", "年龄", "性别", "住址", "电话");
		printf("%-20s\t%-4d\t%-10s\t%-15s\t%-13s\n", p->data[pos].name
			, p->data[pos].age
			, p->data[pos].sex
			, p->data[pos].addr
			, p->data[pos].tele);
	}
}
//修改
void revcon(contacts* p)
{
	assert(p);
	char name[20] = { 0 };
	printf("请输入要修改的联系人姓名:>");
	scanf("%s", name);
	int pos = find(p, name);
	if (-1 == pos)
		printf("无此联系人\n");
	else
	{
		printf("请输入姓名:>");
		scanf("%s", p->data[pos].name);
		printf("请输入年龄:>");
		scanf("%d", &(p->data[pos].age));
		printf("请输入性别:>");
		scanf("%s", p->data[pos].sex);
		printf("请输入住址:>");
		scanf("%s", p->data[pos].addr);
		printf("请输入电话:>");
		scanf("%s", p->data[pos].tele);
	}
}

int cmp_int(const void* p1, const void* p2)
{
	assert(p1 && p2);
	return *(int*)p1 - *(int*)p2;
}
int cmp_char(const void* p1, const void* p2)
{
	assert(p1 && p2);
	return strcmp((*(peo*)p1).name, (*(peo*)p2).name);
}
//排序
void sortcon(contacts* p)
{
	printf("*******************************\n");
	printf("******** 1.年龄 2.姓名 ********\n");
	printf("*******************************\n");
	int input = 0;
	scanf("%d", &input);
	if (1 == input)
	{
		qsort(&p->data->age, p->sz, sizeof(peo), cmp_int);
		Showcon(p);
	}
	else
	{
		qsort(&p->data->name, p->sz, sizeof(peo), cmp_char);
	    Showcon(p);
	}
	return;
}
//清除
void purcon(contacts* p)
{
	assert(p);
	p->sz = 0;
	memset(p->data, 0, sizeof(p->data));
}

3.contacts.h
#define _CRT_SECURE_NO_WARNINGS 1

#include <stdio.h>
#include <assert.h>
#include <string.h>
#include <stdlib.h>

#define MAX_PEO 1000
#define MAX_name 20
#define MAX_sex 6
#define MAX_addrO 15
#define MAX_tele 13





typedef struct peoinf//存放个人的信息
{
	char name[MAX_name];
	int age;
	char sex[MAX_sex];
	char addr[MAX_addrO];
	char tele[MAX_tele];
}peo;

typedef struct Contacts//通讯录包括联系人信息和联系人个数
{
	peo data[MAX_PEO];
	int sz;
}contacts;


//初始化通讯录
void ini_con(contacts* p);
//添加联系人信息
void addcon(contacts* p);
//显示通讯录
void Showcon(const contacts* p);
//删除通讯录信息
void delcon(contacts* p);
//查找信息
void findcon(const contacts* p);
//修改联系人信息
void revcon(contacts* p);
//排序通讯录
void sortcon(contacts* p);
//清除通讯录
void purcon(contacts* p);

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

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

相关文章

进程收尾,初识线程

PCB中的信息:常见属性(有关于进程调度) 1)PID:(进程id)是进程中的身份标识&#xff0c;一个机器同一时刻&#xff0c;不可能有两个进程的PID相同&#xff0c;同一个系统的身份标识&#xff0c;进程的身份证号 2)一组内存指针&#xff1a;指名了该进程持有的一些重要数据和要执行…

一文讲解Linux虚拟化KVM-Qemu分析之virtio初探

说明&#xff1a; KVM版本&#xff1a;5.9.1QEMU版本&#xff1a;5.0.0工具&#xff1a;Source Insight 3.5&#xff0c; Visio 概述 从本文开始将研究一下virtio&#xff1b;本文会从一个网卡虚拟化的例子来引入virtio&#xff0c;并从大体架构上进行介绍&#xff0c;有个宏…

惊奇地发现:「精通或熟练使用 Navicat 」成为了业内企业招聘的任职要求之一

2023 年疫情逐渐消散&#xff0c;招聘市场也火热了起来。我们在招聘平台惊奇地发现&#xff1a;许多岗位招聘启事&#xff08;如&#xff1a;前端开发工程师、业务系统开发工程师和高级数据分析师等&#xff09;中提到&#xff0c;具备熟练使用 Navicat 软件成为任职要求之一。…

正版授权|bigmp4 Ai人工智能视频无损放大

bigmp4&#xff0c;使用先进人工智能 AI 模型&#xff0c;能将视频无损高清放大、增强画质、智能补帧使画面丝滑流畅栩栩如生同时支持黑白视频上色和慢动作。 人工智能视频无损放大 使用今年先进人工智能 AI 模型&#xff0c;能将视频无损高清放大、增强画质、智能补帧使画面丝…

Android Volley 基本使用

Android Volley 基本使用 本篇主要介绍 Google 给Android 平台提供的 Volley 一个 Http请求库 , 齐射! 1.概述 Volley是Google 提供的一个小巧的异步请求库,扩展很强支持okhttp,(默认是 Android2.3 及以上基于 HttpURLConnection&#xff0c;2.3 以下基于 HttpClient 实现), V…

<<数据结构>>向上调整建堆和向下调整建堆的分析(特殊情况,时间复杂度分析,两种建堆方法对比,动图)

今天&#xff0c;我来讲讲建堆算法中使用向上调整和向下调整。 目录建堆的应用向上调整建堆向下调整建堆向下调整建堆和向上调整建堆的选择建堆的应用 在数据结构模拟堆中&#xff0c;我们可能会通过输入数组的元素来进行建堆或者在堆排序中&#xff0c;我们也需要建堆&#x…

Kubernetes之网络排查详细文

文章目录前言一、Pod 网络异常1.1 网络异常大概分为如下几类&#xff1a;1.2 那么整个 Pod 网络异常分类可以如下图所示&#xff1a;二、常用网络排查工具2.1 tcpdump2.1.1 抓取示例2.1.2 选项分组2.1.3 过滤 TCP 标记位2.1.4 查找 http 包2.1.5 查找 DNS 流量2.1.6 查找对应流…

财务数字化在企业数字化转型中起到什么作用?

财务数字化在企业数字化转型中起到什么作用&#xff1f;许多企业在推动各大业务部门进行数字化转型时&#xff0c;往往会忽略财务部门。然而&#xff0c;作为掌握公司核心资源与数据和推动企业数字化建设的部门&#xff0c;财务也应成为企业数字化转型的重要突破口。 这篇就用…

Unity 之 Addressable可寻址系统 -- 可寻址系统使用介绍 -- 入门(三)

可寻址系统设置面板使用介绍介绍 -- 入门&#xff08;三&#xff09;一&#xff0c;可寻址系统目录介绍二&#xff0c;可寻址系统面板介绍2.1 Groups - 资源组2.2 Settings - 设置2.3 Profiles - 配置文件2.4 Event Viewer - 事件查看器2.5 Analyze - 分析工具2.6 Hosting - 托…

sklearn GridSearchCV网格搜索和SVM的两个参数 C 和 gamma

GridSearchCV&#xff0c;它存在的意义就是自动调参&#xff0c;只要把参数输进去&#xff0c;就能给出最优化的结果和参数。GridSearchCV用于系统地遍历多种参数组合&#xff0c;通过交叉验证确定最佳效果参数。 引用自&#xff1a;公众号&#xff1a; 写bug的程旭源 个人博客…

学生信息管理系统【JDBC+JS+MYSQL+HTML+JSP+Servlet】(一)

第一次发综合项目&#xff0c;无论是前端还是后端&#xff0c;都应用到了&#xff0c;项目写的很完整&#xff0c;我将分为四篇文章把项目代码写完&#xff0c;多多支持 一&#xff1a;项目背景 学生成绩管理系统是基于互联网的信息管理平台&#xff0c;主要提供成绩录入和查…

黄金的几种征兆

有别于股票、基金等的投资品种&#xff0c;由于现货黄金采用保证金的交易制度&#xff0c;因而使投资者有爆仓的可能。具体而言&#xff0c;爆仓是指在某些特殊条件下&#xff0c;投资者保证金账户中的客户权益变为负值的情形。在黄金交易的实战中&#xff0c;客户爆仓大多与资…

一文搞懂Spring,堪称Spring源码终结者

Spring的影响力想必无需与大家多说&#xff0c;如果你用spring&#xff0c;那么读读源码有助于对你最重要的工具的理解&#xff0c;好的框架源码也可以帮助我们理解什么是好代码。 刚参加工作那会&#xff0c;没想过去读源码&#xff0c;更没想过去改框架的源码&#xff1b;甚…

反序列化渗透与攻防(一)之PHP反序列化漏洞

前言 序列化和反序列化几乎是工程师们每天都要面对的事情&#xff0c;但是要精确掌握这两个概念并不容易&#xff1a;一方面&#xff0c;它们往往作为框架的一部分出现而湮没在框架之中&#xff1b;另一方面&#xff0c;它们会以其他更容易理解的概念出现&#xff0c;例如加密、…

干货 | 涉疫数据的安全应用方案

以下内容整理自清华大学《数智安全与标准化》课程大作业期末报告同学的汇报内容。第一部分&#xff1a;涉疫数据分类及问题剖析一、涉疫数据分类我们以新冠肺炎疫情为例&#xff0c;构建数据图谱&#xff0c;将涉疫数据分为三个大类&#xff0c;八个小类&#xff0c;共分为50项…

数字化营销,为何网站如此重要?

无论你在哪个行业&#xff0c;客户都会期望你有一个网站。没有网站的公司会发出信息&#xff0c;说他们已经停止运营&#xff0c;或者更糟的是&#xff0c;他们与客户失去了直接的联系。 通常企业的自有媒体由您的网站和社交媒体帐户组成。媒体付费广告等赢利媒体的数据不在您的…

你想要的100套HTML模板

好/看/的/网/页/这/都/有/ 目录 01 HTML 02 效果显示 03 文件演示 04 获取文件 源码链接 获取源码&#xff1f;私信&#xff1f;关注&#xff1f;点赞&#xff1f;收藏&#xff1f; 网页设计 Web design 2023/01/12 “Creativity is allowing yourself to make mista…

岁末年初再添佳誉丨Kyligence 荣获多个奖项及榜单认可

过去的一年&#xff0c;Kyligence 持续创新和打磨企业级产品&#xff0c;以全球领先的指标中台及多维数据库产品在金融、零售、制造、医疗等多个行业场景中逐步落地&#xff0c;实现数智化管理与业务的深度融合。岁末年初&#xff0c;Kyligence 再添佳誉&#xff0c;技术产品、…

第二章.线性回归以及非线性回归—多元线性回归

第二章.线性回归以及非线性回归 2.6 多元线性回归 1.特征&#xff1a; 1).单特征&#xff1a; 2).多特征&#xff1a; 有多少个特征就有多少个未知数x 2.多元线性回归模型的使用场景&#xff1a; 当Y值的影响因素不是唯一时&#xff0c;采用多元线性回归。 3.梯度下降法求解…

【自然语言处理】【chatGPT系列】大语言模型可以自我改进

大语言模型可以自我改进《Large Language Models Can Self-Improve》论文地址&#xff1a;https://arxiv.org/pdf/2210.11610.pdf 相关博客 【自然语言处理】【chatGPT系列】大语言模型可以自我改进 【自然语言处理】【ChatGPT系列】WebGPT&#xff1a;基于人类反馈的浏览器辅助…