数据结构之动态顺序表(附带完整程序)

news2024/9/26 20:46:31

🎈基本概念

🌈一.线性表、顺序表的定义

☀️(1)线性表:

是n个具有相同特性的数据元素的有限序列。线性表在逻辑上是线性结构,但在物理上存储时,通常以数组和链式结构的形式存储。

☀️(2)顺序表:

顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储。在数组上完成数据的增删查改。

🌈二.顺序表的分类

☀️(1)静态顺序表:

1.概念:使用定长数组存储元素
2.定义方法:数组使用方括号法,例如:

typedef struct
{
	int age;
	int height;
	double weight;
}Student;
typedef struct
{
	Student stu[100];//Student类型的数组
	int length;//元素的有效个数
	int listsize;//最多容纳多少个元素
}SqList;

3.缺陷:方括号[ ]内只能是定值,一旦定义了大小就不可改变

☀️(2)动态顺序表:

1.概念:使用动态开辟的数组存储元素
2.定义方法:用指针指向数组,例如:

typedef struct
{
	int age;
	int height;
	double weight;
}Student;
typedef struct
{
	Student* stu;//Student类型的数组
	int length;//元素的有效个数
	int listsize;//最多容纳多少个元素
}SqList;

3.相较于静态顺序表,动态顺序表可以改变数组大小,更合理的利用空间

🎈动态顺序表相关操作函数

为方便理解,以一个学生信息表为例。最开始先开辟5个结构体大小的位置,如果后面不够则每次多开辟2个位置;学生信息由年龄、身高、体重3个数据组成。

🌈定义部分

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#define LIST_INIT_SIZE 5
#define INCREASE 2
typedef struct
{
	int age;
	int height;
	double weight;
}Student;
typedef struct
{
	Student* stu;//Student类型的数组
	int length;//元素的有效个数
	int listsize;//最多容纳多少个元素
}SqList;

🌈一.初始化顺序表

int InitList(SqList* L)
{
	//1.申请空间
	L->stu = (Student*)malloc(LIST_INIT_SIZE * sizeof(Student));
	//2.判断是否申请成功
	if (!L->stu)
		exit(-1);//exit(-1)表示退出程序
	//3.如果拿到了内存空间,就初始化顺序表
	L->length = 0;
	L->listsize = LIST_INIT_SIZE;
	return 1;
}

步骤:
👻1.用malloc申请空间
👻2.判断是否申请成功
补:exit和return的区别:exit(-1)表示终止程序,而return只是结束当下函数
👻3.如果拿到了内存空间,就初始化顺序表
length表示有效元素个数,目前为0;listsize表示数组当前最大容量,假设初始最大容量LIST_INIT_SIZE为5

🌈二.销毁顺序表

int DeleteList(SqList* L)
{
	//1.判断顺序表是否存在
	if (L->stu == NULL)//说明不存在
		return 0;//不可以解引用NULL
	//2.如果存在,则释放对应的内存
	free(L->stu);
	L->stu = NULL;
	//3.释放内存后,恢复表的初始值
	L->length = 0;
	L->listsize = 0;
	return 1;
}

步骤:
👻1.判断顺序表是否存在
如果不存在,直接退出程序,没必要进行后续操作
👻2.如果存在,则释放对应的内存
注:好习惯是只要用完free,就将指针置为NULL
👻3.释放内存后,恢复表的初始值

🌈三.辅助操作函数

以下两个函数是增删查改过程中频繁用到的操作,为防止代码冗余,将重复工作的代码封装成相应的两个函数

☀️(1)元素复制函数(CopyValue)

//元素复制
void CopyValue(Student* s1, Student* s2)
{
	s1->age = s2->age;
	s1->height = s2->height;
	s1->weight = s2->weight;
}

注:需要传两组数据的地址,因为形参的改变不影响实参
s1是元素复制后的位置,s2是元素复制前的位置

☀️(2)输入信息函数(Print)

void Print(Student* onestu)
{
	printf("请输入:\n");
	printf("年龄:");
	scanf("%d", &onestu->age);
	printf("身高:");
	scanf("%d", &onestu->height);
	printf("体重:");
	scanf("%lf", &onestu->weight);
}

在首次大规模插入信息、插入单个信息、查找信息、改动信息等时候都需要输入信息

🌈四.(增)扩大顺序表长度

//扩大数组长度
void ExpandList(SqList* L)
{
	//1.申请内存
	Student* p = (Student*)realloc(L->stu, (L->listsize + INCREASE) * sizeof(Student));
	//2.判断是否申请成功
	if (!p)
		exit(-1);
	//3.如果申请到了内存,更新顺序表的信息(包括学生数组、最大容纳学生量)
	L->stu = p;
	L->listsize += INCREASE;
}

步骤:
👻1.申请内存
由于初始化时已经由malloc初次申请了部分空间,以后每次增加空间都是在初始基础上增加,因此用realloc来扩大顺序表。
🌟realloc使用时的注意事项:
①realloc的第二个参数不是增加了多少空间,而是要扩大至多大的空间,即整个大空间的大小
②用一个新的Student类型的指针接收realloc的返回值,当返回值不为NULL时再将值赋给指向数组的指针L->stu
👻2.判断是否申请成功
👻3.如果申请到了内存,更新顺序表的信息(包括学生数组位置、最大容纳学生量)

☀️(1)对顺序表大规模插入信息

int InsertValue(SqList* L, int n)
{
	//1.确保有足够空间存放信息
	while (L->listsize < n)
	{
		ExpandList(L);
		if (L->listsize >= n)
			break;
	}
	//2.有足够空间,开始插入信息
	for (int i = 0;i < n;i++)
	{
		Print(&L->stu[i]);
		printf("已成功增加一组信息\n");
		L->length++;
	}
	return 1;
}

步骤:
1.确保有足够空间存放信息
2.有足够空间,开始插入信息

☀️(2)在顺序表尾部插入元素

//在顺序表尾部插入元素
void InsertLastList(SqList* L, Student* onestu)
{
	//1.判断数组满没满,满就扩大数组长度
	if (L->length >= L->listsize)
		ExpandList(L);
	//2.有足够空间,在尾部插入新元素(将新元素拷贝到数组末尾)
	CopyValue(&L->stu[L->length], onestu);
	//3.更新学生数量
	L->length++;
}

第二个参数onestu是被插入的信息
步骤:
👻1.判断数组满没满,满就用ExpandList函数扩大数组长度。
👻2.有足够空间,在尾部插入新元素(将新元素拷贝到数组末尾)
👻3.更新学生数量

☀️(3)在顺序表头部插入元素

//在顺序表头部插入元素
void InsertFirstList(SqList* L, Student* onestu)
{
	//1.判断数组满没满,满就扩大数组长度
	if (L->length >= L->listsize)
		ExpandList(L);
	//2.有足够空间,先将所有元素向后挪动1位,
	//  从后往前挪,要不然会被覆盖
	for (int i = L->length-1;i>=0;i--)
	{
		CopyValue(&L->stu[i + 1], &L->stu[i]);
	}
	//3.将新元素拷贝到数组开头
	CopyValue(&L->stu[0], onestu);
	//4.更新学生数量
	L->length++;
}

第二个参数onestu是被插入的信息
步骤:
👻1.判断数组满没满,满就用ExpandList函数扩大数组长度。
👻2.有足够空间,先将所有元素向后挪动1位。
注:要从最后一个元素开始往前挪,如果从前往后挪的话,会将数组中的所有元素全部覆盖成第一个元素。
👻3.将新元素拷贝到数组开头
👻4.更新学生数量

☀️(4)在顺序表指定位置插入元素

//在顺序表指定位置插入元素
int InsertLocList(SqList* L, int i, Student* onestu)
{
	//1.判断位置是否合法
	if (i < 0 || i >= L->length)
	{
		return 0;
	}
	//2.判断数组是否有空位,没有的话扩容
	if (L->length == L->listsize)
	{
		ExpandList(L);
	}
	//3.将插入点及后面的元素向后移动1位
	for (int j = L->length - 1;j >= i;j--)//j>=i+1
	{
		//注1:要从数组的最后一个元素依次向后挪动1位,如果从插入点
		//     开始挪动的话,数组原先的内容会被覆盖
		//注2:j必须要能等于i,因为i是插入点,要连同插入点往后挪1位
		CopyValue(&L->stu[j + 1], &L->stu[j]);
	}
	//4.插入元素
	CopyValue(&L->stu[i], onestu);
	//5.更新表中的信息
	L->length++;
	return 1;
}

第二个参数onestu是被插入的信息
步骤:
👻1.判断位置是否合法
👻2.判断数组是否有空位,没有的话扩容
👻3.将插入点及后面的元素向后移动1位
注:
①要从数组的最后一个元素依次向后挪动1位,如果从插入点开始挪动的话,数组原先的内容会被覆盖
②j必须要能等于i,因为i是插入点,要连同插入点往后挪1位
👻4.插入元素
👻5.更新表中的信息

🌈五.(删)删除顺序表中的信息

void DropOneValue(SqList*L,Student* onestu4)
{
	//1.判断是否有该组数据
	int ret = FindOneList(L, onestu4);
	if (ret == -1)
	{
		printf("没有该信息\n");
		return;
	}
	//2.进行删除
	for (int i = ret + 1;i <= L->length - 1;i++)
	{
		CopyValue(&L->stu[i - 1], &L->stu[i]);
	}
	printf("删除成功\n");
	//3.成员数量信息变动
	L->length--;
}

第二个参数onestu4是要被删除的信息
步骤:
👻1.判断是否有该组数据
👻2.有信息的话进行删
将删除点后面的所有元素向前挪动1位
👻3.成员数量信息变动

🌈六.(查)查找顺序表中的某个元素

int FindOneList(SqList* L, Student* onestu3)
{
	int i = 0;
	while (i < L->length)
	{
		if ((L->stu[i].age == onestu3->age)
			&& (L->stu[i].height == onestu3->height)
			&& (L->stu[i].weight == onestu3->weight))
		return i;
		i++;
	}
	return -1;
}

第二个参数onestu3是被查找的信息
👻1.找到的话返回这个元素在数组中的下标;找不到的话返回-1(为什么不返回0,因为下标也有可能是0)
👻2.需要增加一组Student类型的数据作为对照信息(你肯定要先告诉我你要找的人的信息我才能找到这个人存不存在、存在的话是几号)

🌈七.(改)改变顺序表中某元素信息

void ModifyOneValue(SqList* L, Student* onestu5, Student* onestu6)
{
	//1.判断该信息是否存在
	int ret=FindOneList(L, onestu5);
	if (ret == -1)
	{
		printf("没有该信息\n");
		return;
	}
	//2.信息存在,进行修改
	printf("请输入修改后信息:\n");
	Print(onestu6);
	CopyValue(&L->stu[ret], onestu6);
}

参数二onestu5是改变前的信息,第三个参数onestu6是改变后的信息
步骤:
👻1.判断该信息是否存在
👻2.信息存在,进行修改

🌈八.遍历顺序表打印出所有元素

//遍历顺序表
void FindAllList(SqList* L)
{
	int i = 0;
	for (i = 0;i < L->length;i++)
	{
		printf("age=%d,height=%d,weight=%lf\n", L->stu[i].age,
			L->stu[i].height, L->stu[i].weight);
	}
}

🎈用动态顺序表实现学生信息操作程序

(完整程序,连着的三部分)

🌈一.声明与定义

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#define LIST_INIT_SIZE 5
#define INCREASE 2
typedef struct
{
	int age;
	int height;
	double weight;
}Student;
typedef struct
{
	Student* stu;//Student类型的数组
	int length;//元素的有效个数
	int listsize;//最多容纳多少个元素
}SqList;

🌈二.被调用函数

//初始化顺序表
int InitList(SqList* L)
{
	//1.申请空间
	L->stu = (Student*)malloc(LIST_INIT_SIZE * sizeof(Student));
	//2.判断是否申请成功
	if (!L->stu)
		exit(-1);//exit(-1)表示退出程序
	//3.如果拿到了内存空间,就初始化顺序表
	L->length = 0;
	L->listsize = LIST_INIT_SIZE;
	return 1;
}
//销毁顺序表
int DeleteList(SqList* L)
{
	//1.判断顺序表是否存在
	if (L->stu == NULL)//说明不存在
		return 0;//不可以解引用NULL
	//2.如果存在,则释放对应的内存
	free(L->stu);
	L->stu = NULL;
	//3.释放内存后,恢复表的初始值
	L->length = 0;
	L->listsize = 0;
	return 1;
}
//遍历顺序表
void FindAllList(SqList* L)
{
	int i = 0;
	for (i = 0;i < L->length;i++)
	{
		printf("age=%d,height=%d,weight=%lf\n", L->stu[i].age,
			L->stu[i].height, L->stu[i].weight);
	}
}
//查找学生数组中的某个元素,找到返回元素对应下标,找不到返回0
int FindOneList(SqList* L, Student* onestu3)
{
	int i = 0;
	while (i < L->length)
	{
		if ((L->stu[i].age == onestu3->age)
			&& (L->stu[i].height == onestu3->height)
			&& (L->stu[i].weight == onestu3->weight))
		return i;
		i++;
	}
	return -1;
}
//扩大数组长度
void ExpandList(SqList* L)
{
	//1.申请内存
	Student* p = (Student*)realloc(L->stu, (L->listsize + INCREASE) * sizeof(Student));
	//2.判断是否申请成功
	if (!p)
		exit(-1);
	//3.如果申请到了内存,更新顺序表的信息(包括学生数组、最大容纳学生量)
	L->stu = p;
	L->listsize += INCREASE;
}
//元素复制
void CopyValue(Student* s1, Student* s2)
{
	s1->age = s2->age;
	s1->height = s2->height;
	s1->weight = s2->weight;
}
//在顺序表尾部插入元素
void InsertLastList(SqList* L, Student* onestu)
{
	//1.判断数组满没满,满就扩大数组长度
	if (L->length >= L->listsize)
		ExpandList(L);
	//2.有足够空间,在尾部插入新元素(将新元素拷贝到数组末尾)
	CopyValue(&L->stu[L->length], onestu);
	//3.更新学生数量
	L->length++;
}
//在顺序表头部插入元素
void InsertFirstList(SqList* L, Student* onestu)
{
	//1.判断数组满没满,满就扩大数组长度
	if (L->length >= L->listsize)
		ExpandList(L);
	//2.有足够空间,先将所有元素向后挪动1位,
	//  从后往前挪,要不然会被覆盖
	for (int i = L->length-1;i>=0;i--)
	{
		CopyValue(&L->stu[i + 1], &L->stu[i]);
	}
	//3.将新元素拷贝到数组开头
	CopyValue(&L->stu[0], onestu);
	//4.更新学生数量
	L->length++;
}
//在顺序表指定位置插入元素
int InsertLocList(SqList* L, int i, Student* onestu)
{
	//1.判断位置是否合法
	if (i < 0 || i >= L->length)
	{
		return 0;
	}
	//2.判断数组是否有空位,没有的话扩容
	if (L->length == L->listsize)
	{
		ExpandList(L);
	}
	//3.将插入点及后面的元素向后移动1位
	for (int j = L->length - 1;j >= i;j--)//j>=i+1
	{
		//注1:要从数组的最后一个元素依次向后挪动1位,如果从插入点
		//     开始挪动的话,数组原先的内容会被覆盖
		//注2:j没必要等于i,j--时值为i-1,会把插入点之前的值也往后移动1位
		CopyValue(&L->stu[j + 1], &L->stu[j]);
	}
	//4.插入元素
	CopyValue(&L->stu[i], onestu);
	//5.更新表中的信息
	L->length++;
	return 1;
}
//提示输入信息
void Print(Student* onestu)
{
	printf("请输入:\n");
	printf("年龄:");
	scanf("%d", &onestu->age);
	printf("身高:");
	scanf("%d", &onestu->height);
	printf("体重:");
	scanf("%lf", &onestu->weight);
}
//大规模插入数据
int InsertValue(SqList* L, int n)
{
	//1.确保有足够空间存放信息
	while (L->listsize < n)
	{
		ExpandList(L);
		if (L->listsize >= n)
			break;
	}
	//2.有足够空间,开始插入信息
	for (int i = 0;i < n;i++)
	{
		Print(&L->stu[i]);
		printf("已成功增加一组信息\n");
		L->length++;
	}
	return 1;
}
//删除一个元素(一组学生信息)
void DropOneValue(SqList*L,Student* onestu4)
{
	//1.判断是否有该组数据
	int ret = FindOneList(L, onestu4);
	if (ret == -1)
	{
		printf("没有该信息\n");
		return;
	}
	//2.有信息的话进行删除
	for (int i = ret + 1;i <= L->length - 1;i++)
	{
		CopyValue(&L->stu[i - 1], &L->stu[i]);
	}
	printf("删除成功\n");
	//3.成员数量信息变动
	L->length--;
}
//更改一个元素(一组学生信息)
void ModifyOneValue(SqList* L, Student* onestu5, Student* onestu6)
{
	//1.判断该信息是否存在
	int ret=FindOneList(L, onestu5);
	if (ret == -1)
	{
		printf("没有该信息\n");
		return;
	}
	//2.信息存在,进行修改
	printf("请输入修改后信息:\n");
	Print(onestu6);
	CopyValue(&L->stu[ret], onestu6);
}

🌈三.主函数

int main()
{
	//1.创建变量
	SqList L;
	Student onestu, onestu2,onestu3,
	onestu4,onestu5,onestu6,onestu7;
	//2.初始化(初步申请空间)
	InitList(&L);
	//3.初步整体性插入学生信息
	printf("1.整体插入信息\n");
	int n = 0;
	printf("请输入学生个数:\n");
	scanf("%d", &n);
	InsertValue(&L, n);
	//4.在末尾处插入学生信息
	printf("2.在数组末尾处插入学生信息\n");
	Print(&onestu);
	InsertLastList(&L, &onestu);
	//5.在开头处插入学生信息
	printf("3.在数组开头处插入学生信息\n");
	Print(&onestu7);
	InsertFirstList(&L, &onestu7);
	//6.在指定位置插入学生信息
	printf("4.在指定位置处插入学生信息\n");
	printf("请输入要插入的位置:");
	int i = 0;
	scanf("%d", &i);
	Print(&onestu2);
	InsertLocList(&L, i, &onestu2);
	//7.查找学生数组中的某个元素
	printf("5.查找某名学生\n");
	Print(&onestu3);
	int ret = FindOneList(&L, &onestu3);
	if (ret == 0)
		printf("没有该名学生\n");
	else
		printf("该名学生的编号是%d\n", ret);
	//8.删除表中元素
	printf("6.删除表中一组信息:\n");
	printf("请输入要删除的学生信息:\n");
	Print(&onestu4);
	DropOneValue(&L, &onestu4);
	//9.修改信息
	printf("7.修改表中信息\n");
	printf("请输入被修改学生信息:\n");
	Print(&onestu5);
	ModifyOneValue(&L, &onestu5, &onestu6);
	//10.展示最终顺序表(所有插入的信息)
	printf("8.展示最终学生信息表\n");
	FindAllList(&L);
	//10.释放空间
	DeleteList(&L);
}

🌈运行结果

我在输入学生信息的时候用数字代替了😂
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

感谢浏览,如有错误请及时指正!❤️

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

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

相关文章

C# 关于使用newlife包将webapi接口寄宿于一个控制台程序、winform程序、wpf程序运行

C# 关于使用newlife包将webapi接口寄宿于一个控制台程序、winform程序、wpf程序运行 安装newlife包 Program的Main()函数源码 using ConsoleApp3; using NewLife.Log;var server new NewLife.Http.HttpServer {Port 8080,Log XTrace.Log,SessionLog XTrace.Log }; serv…

hcip——ospf综合

要求 1. 搭建toop 2.地址规划 协议范围路由器地址 RIP 172.16.0.0 17 R12 loop0&#xff1a;172.16.0.0 24 loop1&#xff1a;172.16.1.0 24 OSPF 172.16.128.0 17 area1 172.16.144.0 20 R1 g0:172.16.144.1 24 loop0:172.16.145.1 24 R2 g0:172.16.144.2 24 loop:172…

iOS - Apple开发者账户添加新测试设备

获取UUID 首先将设备连接XCode&#xff0c;打开Window -> Devices and Simulators&#xff0c;通过下方位置查看 之后登录(苹果开发者网站)[https://developer.apple.com/account/] &#xff0c;点击设备 点击加号添加新设备 填写信息之后点击Continue&#xff0c;并一路继续…

Golang Devops项目开发(1)

1.1 GO语言基础 1 初识Go语言 1.1.1 开发环境搭建 参考文档&#xff1a;《Windows Go语言环境搭建》 1.2.1 Go语言特性-垃圾回收 a. 内存自动回收&#xff0c;再也不需要开发人员管理内存 b. 开发人员专注业务实现&#xff0c;降低了心智负担 c. 只需要new分配内存&#xff0c;…

Android系统服务之AMS

目录 概述 重点和难点问题 启动方式 main入口&#xff1a; run方法&#xff1a; BootstrapSevices 小结&#xff1a; 与其他线程的通信原理 参考文档&#xff1a; 概述 AMS是Android系统主要负责四大组件的启动&#xff0c;切换&#xff0c;调度以及应用程序进程管理和调度等工…

watch避坑,使用computed进行处理数据

业务场景&#xff1a;在vue中监听el-input 中的字数有没有超过60&#xff0c;如果超过60字时将60后面的字变为 “>>” 符号&#xff0c;以此实现预览苹果手机推送摘要场景。 错误&#xff1a;开始的逻辑是使用watch监听&#xff0c;检查length超过60直接 加上符号&#x…

选好NAS网络储存解决方案,是安全储存的关键

随着网络信息的发展&#xff0c;NAS也越来越受到企业的关注&#xff0c;NAS网络存储除了提供简单的存储服务外&#xff0c;还可以提供更好的数据安全性、更方便的文件共享方式。但市面上的产品种类繁多&#xff0c;我们该如何选择合适的产品&#xff0c;通过企业云盘&#xff0…

spring5源码篇(12)——spring-mvc请求流程

spring-framework 版本&#xff1a;v5.3.19 文章目录 一、请求流程1、处理器映射器1.1、 RequestMappingHandlerMapping1.2、获取对应的映射方法1.3、添加拦截器 2、获取合适的处理器适配器3、通过处理器适配器执行处理器方法3.1、拦截器的前置后置3.2、处理器的执行3.2.1 参数…

Unity 性能优化二:内存问题

目录 策略导致的内存问题 GFX内存 纹理资源 压缩格式 Mipmap 网格资源 Read/Write 顶点数据 骨骼 静态合批 Shader资源 Reserved Memory RenderTexture 动画资源 音频资源 字体资源 粒子系统资源 Mono堆内存 策略导致的内存问题 1. Assetbundle 打包的时候…

【C++】C++ STL标准模板库知识点总结(秋招篇)

文章目录 前言STL的六大组件是&#xff1f;容器(container) 算法(algorithm) 迭代器(iterator) 三者的关系&#xff1f;容器分为几种&#xff1f;分别有哪些&#xff1f;关联性容器和非关联性容器有什么区别&#xff1f;Vector容器是怎么调整大小的&#xff1f;&#xff08;内存…

VirtualEnv 20.24.0 发布

导读VirtualEnv 20.24.0 现已发布&#xff0c;VirtualEnv 用于在一台机器上创建多个独立的 Python 运行环境&#xff0c;可隔离项目之间的第三方包依赖&#xff0c;为部署应用提供方便&#xff0c;把开发环境的虚拟环境打包到生产环境即可&#xff0c;不需要在服务器上再折腾一…

RAM明明断电会丢失数据,为什么初始化的全局变量存储在RAM?详细分析程序的存储

前言 &#xff08;1&#xff09;之前因为一个字符指针和字符数组指针引发的bug&#xff0c;折磨了我一个下午才发现问题。之后我就打算研究一下系统是如何发现野指针乱访问问题。后面就一直深入到微机系统中的内存管理了。 &#xff08;2&#xff09;这些其实都是基础知识&…

SpringBoot房屋租赁系统【附ppt|万字文档(LW)和搭建文档】

主要功能 前台登录&#xff1a; ①首页&#xff1a;公告信息、房屋信息展示、查看更多等 ②房屋信息、房屋类型、我要当房主、公告信息、留言反馈等 ③个人中心&#xff1a;可以查看自己的信息、更新图片、更新信息、退出登录、我的收藏 后台登录&#xff1a; ①首页、个人中心…

Day 69-70:矩阵分解

代码&#xff1a; package dl;import java.io.*; import java.util.Random;/** Matrix factorization for recommender systems.*/public class MatrixFactorization {/*** Used to generate random numbers.*/Random rand new Random();/*** Number of users.*/int numUsers…

使用贝叶斯算法完成文档分类问题

贝叶斯原理 贝叶斯原理&#xff08;Bayes theorem&#xff09;是一种用于计算条件概率的数学公式。它是以18世纪英国数学家托马斯贝叶斯&#xff08;Thomas Bayes&#xff09;的名字命名的。贝叶斯原理表达了在已知某个事件发生的情况下&#xff0c;另一个事件发生的概率。具体…

【Golang系统开发】搜索引擎(1) 如何快速判断网页是否已经被爬取

文章目录 1. 写在前面2. 数组存储3. 位图存储3.1 位图简介3.2 链表法3.3 开放寻址法 1. 写在前面 在实际工作中&#xff0c;我们经常需要判断一个对象是否存在&#xff0c;比如判断用户注册登陆时候&#xff0c;需要判断用户是否存在&#xff0c;再比如搜索引擎中的爬虫&#x…

大数据面试题之Elasticsearch:每日三题(七)

大数据面试题之Elasticsearch:每日三题 1.Elasticsearch索引文档的流程&#xff1f;2.Elasticsearch更新和删除文档的流程&#xff1f;3.Elasticsearch搜索的流程&#xff1f; 1.Elasticsearch索引文档的流程&#xff1f; 协调节点默认使用文档ID参与计算(也支持通过routing)&a…

【UE4】给角色添加脚步声

步骤&#xff1a; 1. 导入一个脚步声音频文件&#xff08;.wav格式&#xff09; 2. 打开角色蓝图&#xff0c;这里以第三人称角色模板蓝图“ThirdPersonCharacter”为例&#xff0c;在事件图表中添加一个生成音效的自定义事件。 3. 打开动画序列“ThirdPersonRun” 找到小白人…

Python编程——while循环嵌套讲解(附案例)

作者&#xff1a;Insist-- 个人主页&#xff1a;insist--个人主页 本文专栏&#xff1a;Python专栏 专栏介绍&#xff1a;本专栏为免费专栏&#xff0c;并且会持续更新python基础知识&#xff0c;欢迎各位订阅关注。 目录 一、while嵌套的语法 二、注意事项 三、while嵌套循…

【Java】分支结构习题

【Java】分支结构 文章目录 【Java】分支结构题1 &#xff1a;数字9 出现的次数题2 &#xff1a;计算1/1-1/21/3-1/41/5 …… 1/99 - 1/100 的值。题3 &#xff1a;猜数字题4 &#xff1a;牛客BC110 X图案题5 &#xff1a;输出一个整数的每一位题6 &#xff1a; 模拟三次密码输…