顺序表--数据结构第一关

顺序表

数据结构概念

定义:数据结构是计算机存储、组织数据的⽅式

根据学过C语言的基础上,数组是最简单的数据结构

顺序表的底层就是数组

为什么呢?

例子如下:

int arr[100]={1,2,3,4,5};
//修改某一个数据:arr[pos]=x;
//插入一个元素:找到数组已有元素,再进行插入数据
//删除一个元素,找到数组已有元素,再进行删除数据    

这个情况还是我们可见的情况下,如果说是好多数组要进行这样的操作,或者很大的未知大小的数组要进行如下的操作,是不是特别麻烦

顺序表说:我虽然底层是数组,但是我提供了很多现成的方法,开箱即用,我就变成了一个很厉害的数据结构。

数组和顺序表的对比

数组(苍蝇馆子)顺序表(米其林)
炒土豆丝豪华金丝(炒土豆丝+摆盘)
蔬菜汤西湖牛肉羹(蔬菜+水+摆盘)

由此可以形象地表现出顺序表:在数组的基础上增加了增删改查的方法

顺序表也是一种线性表

线性表是具有相同性质的数据结构的集合

初步理解

蔬菜分为绿叶类、⽠类、菌菇类。

水果有:香蕉,苹果,菠萝。。。。

那线性表是具有相同性质的数据结构的集合具体表现在哪两个方面呢?

(1):物理结构:不一定连续

​ (2):逻辑结构:连续的

如图所示:

在这里插入图片描述

这个是物理结构上的理解

逻辑结构就是我们通常所认为的理解。

打个比方,我们去商店购物:如果是比较火的店就需要排队

在这里插入图片描述

右边那串像葡萄一样的,可以抽象理解为一个连续的结构,再来看数组,数组是连续存放的,我们可以通过指针的方式,去访问数组里面的元素,所以数组是逻辑结构上连续的

再来看顺序表

顺序表的底层是数组,所以它的物理结构和逻辑结构都是连续的

接下来做一个知识的铺垫引入:

int arr[10]={0};//定长数组
int* arr;//动态内存开辟,确定大小之后再去动态申请

顺序表的分类

静态顺序表

struct SeqList
{
    int arr[100];//定长数组
    int size;//顺序表当前有效的数据个数;
}

动态顺序表

struct SeqList
{
    int* arr;
    int size;//有效的数据个数
    int capcity;//空间大小
    
}

那么这两种哪一种更好呢?

首先我们来谈静态顺序表

(1)数组大小给小了,空间不够用 :如果说开发一个APP,你只提供了能储存一万个用户信息的空间,但是这款APP,却意外的火了,现在有很多很多用户想要去注册,但是没有空间可以注册,这样子给公司造成了不小的损失。

(2)数组大小给大了,空间造成了浪费:这样子也会给公司造成了一定的损失

接着我们再来谈动态顺序表:

动态增容:譬如说只开辟了100个空间,但是我们可以动态地扩容,相较于静态顺序表来说浪费的更少了

这里我们不难得出答案:动态顺序表更好
在这里插入图片描述

在这里插入图片描述

顺序表的实现

在这里插入图片描述

这就好比一本书的目录一样,头文件就相当于是目录的作用

Seq就是 sequence 的意思,也就是顺序的意思,List顾名思义就是列表

注意这里还需要创建一个源文件作为测试用叫test.c

注意来看:

#define _CRT_SECURE_NO_WARNINGS 1
//一般不推荐写静态顺序表
//以下是动态顺序表
typedef int SLDataType;
struct SeqList
{
	SLDataType* arr;
	int size;//有效的数据大小
	int capacity;//空间大小
};

为什么我这里还要重新定义int ,而不是直接写int 呢?

打个比方,我们以后进了公司,有100000000行的代码涉及到了int ,这时候领导来了一句,把其中的6000行换成char,虽然我们知道编译器有一键置换的功能,但是这个功能可不能轻易使用,我们只要换其中的6000行不是所有的,所以我们要用重命名的方法来做,提高了我们的效率。

初始化和销毁

注意点:

在这里插入图片描述

来看一些代码的实现:

头文件内的:

#pragma once
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>
//一般不推荐写静态顺序表
//以下是动态顺序表
typedef int SLDataType;
struct SeqList
{
	SLDataType* arr;
	int size;//有效的数据大小
	int capacity;//空间大小
}SL;
//顺序表的初始化
void SLInit(SL* ps);
//顺序表的销毁
void SLDestory(SL* ps);
//头部插⼊删除 / 尾部插⼊删除
void SLPushBack(SL* ps, SLDataType x);
void SLPopBack(SL* ps);
void SLPushFront(SL* ps, SLDataType x);
void SLPopFront(SL* ps);

SeqList.c:

#define _CRT_SECURE_NO_WARNINGS 1
#include "SeqList.h"
void SLInit(SL *ps)
{
	ps->arr = NULL;
	ps->size = ps->capcacity = 0;
}
void SLDestory(SL* ps)
{
	if (ps->arr)
	{
		free(ps->arr);
	}
	ps->arr = NULL;
	ps->size = ps->capcacity = 0;
}

test.c:

#include "SeqList.h"
int main()
void SLTest01()
{
	SL sl;
	SLInit(&sl);
}
int main()
{
	SLTest01();
	return 0;
}

尾插

对尾插的概念图解:

在这里插入图片描述

ps指向的是一个数组,X=5是我要插入的数,size是我有效的数字个数,在这幅图中有4个,capacity是指空间大小

接下来是代码的实现过程了:

这是在SeqLsit.c的内容:

//尾插
void SLPushBack(SL* ps, SLDataType x)
{
	//ps->arr[ps->size]=x;
	//++ps->size;
	ps->arr[ps->size++];//这行代码是将上面的两行代码变成了一行代码,
	//对其size进行了后置++,提高程序运行效率
}

这是在test.c的内容:

void SLTest01()
{
	SL sl;
	SLInit(&sl);
	//增删查改操作
	//测试尾插
	SLPushBack(&sl, 1);
	SLDestory(&sl);
}

但是这样做在运行的时候会出现一些问题:
当你去监视程序的时候会发现:

size和capacity为0,也就意味着没有创建顺序表去可以去接受内容

这样就给我们提了一个醒:

插入数据前先看空间够不够

代码如下:

if(ps->capacity==ps->size)

如果不够,接下来我们就要去申请空间了

申请空间就不难想到之前学过的三个有关动态开辟空间的函数:malloc,calloc,realloc

经典的三选一:我们选择realloc,因为在这三个函数中只有realloc有增容的概念,其他两个都只是开辟空间,在这里又要注意malloc和calloc的区别,calloc开辟空间的时候会对其进行初始化

接下来出现了我们的第一个问题

要申请多大的空间/一次增容多少?

在这里插入图片描述

如上图,我到底是开辟一个还是开辟n个空间呢。

直接给出结论:

增容通常是成倍数的增加,一般是2倍或3倍,但通常来说是2倍的去增容

实际上是数学推理出来的,用2或者3倍更合理

若要频繁地增容,程序运行效率大大降低

空间大小和数据个数的关系
在这里插入图片描述

从图上可以清楚地看出:空间大小和数据个数成正比的关系

以下是一些补充(感兴趣自己看,不感兴趣也无妨,不会影响学习的效率)

在数据结构中,特别是当涉及到数组这样的连续存储结构时,增容(或称为扩容)通常以倍数的形式增加,这样做的主要原因有以下几点:

  1. 减少数据移动次数:当数组需要扩容时,通常的做法是开辟一块新的、更大的内存空间,然后将原数组中的元素复制到新的内存空间中。如果每次扩容只增加少量空间,那么随着数组元素的增加,这种复制操作会频繁发生,导致时间复杂度较高。而如果以倍数形式增加容量,比如每次扩容为原来的两倍,那么虽然单次扩容时复制的元素数量较多,但复制操作的频率会大大降低,从而减少总的复制次数和时间消耗。
  2. 均摊时间复杂度为O(1):当以倍数形式扩容时,可以计算出均摊到每个元素上的复制次数是常数级别的。具体来说,假设每次扩容为原来的两倍,那么最终数组中的n个元素中,n个元素至少被复制了1次,n/2个元素至少被复制了2次,n/4个元素至少被复制了3次,以此类推。将这些复制次数相加,可以得到一个等比数列的和,其和是O(n)的。但由于这个复制次数是分摊到n个元素上的,所以均摊到每个元素上的复制次数是O(1)的。这意味着,从长期来看,每次插入或删除元素的时间复杂度是常数级别的。
  3. 空间利用率:虽然以倍数形式扩容可能会导致一定的空间浪费(因为当数组未满时就已经进行了扩容),但这种浪费是可控的,并且可以通过选择合适的扩容倍数来平衡空间利用率和性能。通常,选择2倍作为扩容倍数是一个较好的折衷方案,因为它既能保证较好的性能,又能保持相对较高的空间利用率。

综上所述,数据结构中增容以倍数的形式增加主要是为了减少数据移动次数、降低均摊时间复杂度和保持相对较高的空间利用率。

代码如下:

ps->arr = realloc(ps->arr, ps->capacity * 2*sizeof(SLDataType));

接下来我们来看我们已经写的代码:

#define _CRT_SECURE_NO_WARNINGS 1
#include "SeqList.h"
void SLInit(SL *ps)
{
	ps->arr = NULL;
	ps->size = ps->capcacity = 0;
}
void SLDestory(SL* ps)
{
	if (ps->arr)
	{
		free(ps->arr);
	}
	ps->arr = NULL;
	ps->size = ps->capcacity = 0;
}
//尾插
void SLPushBack(SL* ps, SLDataType x)
{
	//插入前先看空间够不够
	if (ps->capacity == ps->size)
	{
		//申请空间
		ps->arr = realloc(ps->arr, ps->capacity * 2*sizeof(SLDataType));
	}
	//ps->arr[ps->size]=x;
	//++ps->size;
	ps->arr[ps->size++];//这行代码是将上面的两行代码变成了一行代码,
	//对其size进行了后置++,提高程序运行效率
}

有没有发现什么问题呢?

	ps->size = ps->capcacity = 0;

我把空间初始化为0了,我怎么插入数据呢?

看代码如下:

//判断空间大小是否为0
// 三目表达式
int newCapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;

但是不要忘了动态申请内存可能会失败,realloc申请空间失败会怎样呢?

里面会变成NULL.

例子如下:
在这里插入图片描述

还是来看这幅图:

如果这幅图我要插入的数据大于它所能存储的空间范围呢,那样子不就全都没了,竹篮打水一场空

来看代码的实现:

	SLDataType*tmp = realloc(ps->arr, ps->newCapacity * 2*sizeof(SLDataType));
	if (tmp == NULL)
	{
		perror("realloc fail!");
		exit(1);
	}
	//空间申请成功
	ps->arr = tmp;
	ps->capacity = newCapacity;

我先去判断是否为空,这里还要注意我用了*tmp去接收内容。tmp是临时变量,以防数据丢失

再来看一个坑:

在test.c文件中:

#include "SeqList.h"
int main()
void SLTest01()
{
	SL sl;
	SLInit(&sl);
	//增删查改操作
	//测试尾插
	SLPushBack(&sl, 1);
	SLPushBack(&sl, 2);
	SLPushBack(&sl, 3);
	SLPushBack(&sl, 4);
	SLPushBack(NULL, 5);//注意看这个代码
	SLDestory(&sl);
}
int main()
{
	SLTest01();
	return 0;
}

如果我贸然地将前面的参数变为NULL,此时我们的代码还不具有健壮性,程序会出现访问冲突的问题,此时该怎么做呢?

if (ps == NULL)
{
	return;
}

在插入空间前看是否为空指针。

Tip:在程序运行的时候退出码为0,证明是正常退出的,如果不为0,那就是没有正常退出

这是一种比较温柔的解决方法

下面是比较粗暴的解决方式:

#include <assert.h>
assert(ps);//等价于assert(ps!=NULL);

头插

概念图:

在这里插入图片描述

把元素插到arr[0]的位置

大体思路如下:
在这里插入图片描述

目标是打算把最后一位有效数字往后挪一位

代码如下:

void SLPushFront(SL* ps, SLDataType x)
{
	assert(ps);
	SLCheckCapacity(ps);
	//先让顺序表已有的数据往后挪动一位
	for (int i = ps->size; i > 0; i--)
	{
		ps->arr[i] =ps-> arr[i - 1];//arr[1]=arr[0],最后一次情况是这样,由此来推断i的限制条件
	}
	ps->arr = x;
}

特别需要注意这里i的限制条件,我们不确定的时候可以先往下写,由写出的代码推出for循环的限制条件

接下来的一步我们要去打印顺序表:

void SLPrint(SL s)
{
	for (int i = 0; i < s.size; i++)
	{
		printf("%d ",s.arr[i]);
	}
	printf("\n");
}

为什么这里不要取地址呢?

因为我们要取的是它的值。

但是我们去打印的时候会出现一些不太符合我们预期的结果,在头插上,这是因为有效个数没有增加:

ps->size++;

综合来看代码如下:

void SLPushFront(SL* ps, SLDataType x)
{
	assert(ps);
	SLCheckCapacity(ps);
	//先让顺序表已有的数据往后挪动一位
	for (int i = ps->size; i > 0; i--)
	{
		ps->arr[i] =ps-> arr[i - 1];//arr[1]=arr[0],最后一次情况是这样,由此来推断i的限制条件
		ps->size++;//特别要注意了
	}
	ps->arr = x;
}

尾删

概念图

情况一:

在这里插入图片描述

情况二:

在这里插入图片描述

我们需要知道一个道理:只要写的表达式能够很好地满足增删改查数据就是好的表达式

头删

在这里插入图片描述

代码如下:

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

完整的实现过程:

SeqList.h

#pragma once
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
//一般不推荐写静态顺序表
//以下是动态顺序表
typedef int SLDataType;
struct SeqList
{
	SLDataType* arr;
	int size;//有效的数据大小
	int capacity;//空间大小
}SL;
//顺序表的初始化
void SLInit(SL* ps);
//顺序表的销毁
void SLDestory(SL* ps);
//顺序表的打印
void SLPrint(SL s);
//头部插入删除 / 尾部插入删除
//插入
void SLPushBack(SL* ps, SLDataType x);
void SLPushFront(SL* ps, SLDataType x);
//删除
void SLPopBack(SL* ps);
void SLPopFront(SL* ps);

SeqList.c

#define _CRT_SECURE_NO_WARNINGS 1
#include "SeqList.h"
//专门封装一个函数用来检查空间是否够不够
void SLCheckCapacity(SL*ps)
{
	//插入前先看空间够不够
	if (ps->capacity == ps->size)
	{
		//温柔的解决方法
		if (ps == NULL)
		{
			return;
		}
		//判断空间大小是否为0
		// 三目表达式
		int newCapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;
		//申请空间
		SLDataType* tmp = realloc(ps->arr, ps->newCapacity * 2 * sizeof(SLDataType));
		if (tmp == NULL)
		{
			perror("realloc fail!");
			exit(1);
		}
		//空间申请成功
		ps->arr = tmp;
		ps->capacity = newCapacity;
	}
}
void SLInit(SL *ps)
{
	ps->arr = NULL;
	ps->size = ps->capcacity = 0;
}
void SLDestory(SL* ps)
{
	if (ps->arr)
	{
		free(ps->arr);
	}
	ps->arr = NULL;
	ps->size = ps->capcacity = 0;
}
//尾插
void SLPushBack(SL* ps, SLDataType x)
{
	assert(ps);
	SLCheckCapacity(ps);
	//ps->arr[ps->size]=x;
	//++ps->size;
	ps->arr[ps->size++]=x;//这行代码是将上面的两行代码变成了一行代码,
	//对其size进行了后置++,提高程序运行效率
}
void SLPushFront(SL* ps, SLDataType x)
{
	assert(ps);
	SLCheckCapacity(ps);
	//先让顺序表已有的数据往后挪动一位
	for (int i = ps->size; i > 0; i--)
	{
		ps->arr[i] =ps-> arr[i - 1];//arr[1]=arr[0],最后一次情况是这样,由此来推断i的限制条件
		ps->size++;//特别要注意了
	}
	ps->arr = x;
}

void SLPrint(SL s)
{
	for (int i = 0; i < s.size; i++)
	{
		printf("%d ",s.arr[i]);
	}
	printf("\n");
}
void SLPopBack(SL* ps)
{
	assert(ps);
	assert(ps->size);
	//顺序表不为空
	--ps->size;
}
void SLPopFront(SL* ps)
{
	assert(ps);
	assert(ps->size);
	for (int i = 0; i < size - 2; i++)
	{
		ps->arr[i] = ps->arr[i + 1];//arr[size-2]=arr[size-1];
	}
	ps->size--;
}

test.c

#include "SeqList.h"
int main()
void SLTest01()
{
	SL sl;
	SLInit(&sl);
	//增删查改操作
	//测试尾插
	SLPushBack(&sl, 1);
	SLPushBack(&sl, 2);
	SLPushBack(&sl, 3);
	SLPushBack(&sl, 4);
	//SLPushBack(NULL, 5);
	SLPrint(sl);
	SLPushFront(&sl, 6);
	SLPrint(sl);
	SLDestory(&sl);
}
int main()
{
	SLTest01();
	return 0;
}

思维导图

在这里插入图片描述
送大家一句话:如果你遇到困难的时候,证明你在走上坡路。
希望大家喜欢的博客,如有不足请大家指正!

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

电子部件烧录流程(仅供参考)

&#x1f34e;个人博客&#xff1a;个人主页 &#x1f3c6;个人专栏&#xff1a;日常聊聊 ⛳️ 功不唐捐&#xff0c;玉汝于成 目录 前言 正文 部件烧录流程的详细步骤 1. 准备工作 2. 连接硬件 3. 配置烧录软件 4. 校验和设置 5. 开始烧录 6. 验证和测试 7. 断开…

吉利银河L6 AQS空气质量监控系统

结论 顶配才有AQS 开启空调且auto模式 则默认开启AQS 无法关闭AQS AQS的作用 银河L6 AQS触发 和 图标 AQS官方配置参数 官方文档 吉利用户手册

机器学习基础概念

1.机器学习定义 2.机器学习工作流程 &#xff08;1&#xff09;数据集 ①一行数据&#xff1a;一个样本 ②一列数据&#xff1a;一个特征 ③目标值&#xff08;标签值&#xff09;&#xff1a;有些数据集有目标值&#xff0c;有些数据集没有。因此数据类型由特征值目标值构成或…

数据结构与算法笔记:实战篇 - 剖析微服务接口鉴权限流背后的数据结构和算法

概述 微服务是最近几年才兴起的概念。简单点将&#xff0c;就是把复杂的大应用&#xff0c;解耦成几个小的应用 。这样做的好处有很多。比如&#xff0c;这样有利于团队组织架构的拆分&#xff0c;比较团队越大协作的难度越大&#xff1b;再比如&#xff0c;每个应用都可以独立…

程序算法设计分析

动态规划和分治、贪心相比有什么区别&#xff1f;各自的优缺点&#xff1f; 分治算法特征&#xff1a; 1&#xff09;规模如果很小&#xff0c;则很容易解决。//一般问题都能满足 2&#xff09;大问题可以分为若干规模小的相同问题。//前提 3&#xff09;利用子问题的解&#x…

最靓丽的C++开源通知弹框SnoreToasts自动监听软件及网页通知

SnoreToasts&#xff0c;作为一款轻量级的C开源项目&#xff0c;为开发者提供了一个便捷的方式来在Windows操作系统上展示通知弹框&#xff08;Toast Notifications&#xff09;。 特点与优势 轻量级&#xff1a;SnoreToasts采用了简洁的代码设计&#xff0c;避免了不必要的依…

苹果可能与谷歌大模型合作,马斯克xAI下个月推出Grok-2,比尔·盖茨:Scaling Law快要走到尽头

ChatGPT狂飙160天&#xff0c;世界已经不是之前的样子。 更多资源欢迎关注 1、苹果被曝 Gemini 模型今秋或融入苹果智能生态系统 苹果知名爆料人马克古尔曼&#xff08;Mark Gurman&#xff09;最新透露&#xff0c;苹果公司将于今年秋季宣布与Alphabet旗下的谷歌的大模型Gem…

电流传感器技术详解,你都懂吗?

在任何过程中&#xff0c;电量的测量对于监控、分析和控制系统都是必不可少的。要执行这些类型的测量&#xff0c;必须使用电流传感器。除非可以测量&#xff0c;否则无法管理物理量。让我们深入了解电流传感器的行为。 电流传感器 电流传感器是将电流信号转换为另一个可分析…

PyTorch计算机视觉实战:目标检测、图像处理与深度学习

本书基于真实数据集&#xff0c;全面系统地阐述现代计算机视觉实用技术、方法和实践&#xff0c;涵盖50多个计算机视觉问题。全书分为四部分&#xff1a;一部分介绍神经网络和PyTorch的基础知识&#xff0c;以及如何使用PyTorch构建并训练神经网络&#xff0c;包括输入数据缩放…

从零到一:全面掌握模板机部署与虚拟机克隆的实训指南【实训Day01】

一、模板机的部署 1.设置好子网ip和子网掩码以及网关 保证有NAT模式 子网IP着重记住前三段&#xff1a;192.168.222.xxx 2.开始建立虚拟机 注意&#xff1a;路径中不要有中文 3.安排8个内核 4.安排2GB内存 创建初步成功&#xff0c;接着 5.开启此虚拟机 6.选择中文 7.日期&…

好展位,抢先订!2024年亚洲(泰国) 国际电力能源展

2024年亚洲&#xff08;泰国&#xff09; 国际电力能源展 Powerex Asia & Electric Asia 2024 ▏发电设备 ▏输配电 ▏电网 ▏太阳能光伏 ▏储能 ▏氢能 ▏生物能源 ▏风能 ▏智慧能源 ▏ 能源部官方批复亚洲重点电力及新能源展 展会时间&#xff1a;2024 年 10 月 16-…

R可视化数据必要格式——长格式

一、引言 我们在对数据进行可视化时遇到最头疼、最常见的问题是什么&#xff1f;数据问题。 因为我们往往不会从零自己编程进行可视化&#xff0c;往往是现有模板或积累&#xff0c;而正确的数据格式对应正确的图形包要求&#xff0c;一定会正确出图&#xff0c;所以只有一个问…

鸿蒙开发设备管理:【@ohos.settings (设置数据项名称)】

设置数据项名称 说明&#xff1a; 本模块首批接口从API version 8开始支持。后续版本如有新增内容&#xff0c;则采用上角标单独标记该内容的起始版本。 本模块提供设置数据项的访问功能相关接口的说明及示例。 导入模块 import settings from ohos.settings;settings.getUri…

Pointnet++改进即插即用系列:全网首发GLSA聚合和表示全局和局部空间特征|即插即用,提升特征提取模块性能

简介:1.该教程提供大量的首发改进的方式,降低上手难度,多种结构改进,助力寻找创新点!2.本篇文章对Pointnet++特征提取模块进行改进,加入GLSA,提升性能。3.专栏持续更新,紧随最新的研究内容。 目录 1.理论介绍 2.修改步骤 2.1 步骤一 2.2 步骤二 2.3 步骤三 1.理论介…

Java中==和equals()的区别

Java中和equals&#xff08;&#xff09;的区别 1、操作符2、equals()方法3、总结 &#x1f496;The Begin&#x1f496;点点关注&#xff0c;收藏不迷路&#x1f496; 在Java中&#xff0c;和equals()是两个常用的比较操作符和方法&#xff0c;但它们之间的用法和含义却有着本…

GPT-5即将登场:AI赋能下的未来工作与日常生活新图景

随着OpenAI首席技术官米拉穆拉蒂在近期采访中的明确表态&#xff0c;GPT-5的发布已不再是遥不可及的梦想&#xff0c;而是即将在一年半后与我们见面的现实。这一消息无疑在科技界乃至全社会引发了广泛关注和热烈讨论。从GPT-4到GPT-5的飞跃&#xff0c;被形容为从高中生到博士生…

03.C1W2.Sentiment Analysis with Naïve Bayes

目录 Probability and Bayes’ RuleIntroductionProbabilitiesProbability of the intersection Bayes’ RuleConditional ProbabilitiesBayes’ RuleQuiz: Bayes’ Rule Applied Nave Bayes IntroductionNave Bayes for Sentiment Analysis P ( w i ∣ c l a s s ) P(w_i|clas…

【笔记】太久不用redis忘记怎么后台登陆了

&#xff01;首先启动虚拟机linux的centos7 2.启动finalshell 我的redis启动在根目录用 redis-server redis.conf --启动 systemctl status redis --查看redis状态 是否active redis-cli -h centos的ip地址 -p 你要用的redis端口号&#xff08;默认为6379&#xff09; -a 你…

JavaSE阶段面试题(一)

目录 1.int a 1, int b 1, Integer c 1, Integer d 1&#xff1b;四个区别和联系&#xff0c;以及c和d是同一个吗&#xff1f; 2.为什么重写HashCode必须重写euqals&#xff0c;两者之间的关系&#xff1f; 3.创建对象的方式有哪些 4.重写和重载的区别 5.抽象类和接口…

firewalld(6)自定义services、ipset

简介 在前面的文章中我们已经介绍了zone、rich rule 、--direct等功能和基本配置。在前面文章中&#xff0c;我们提到过firewalld内置了很多服务&#xff0c;可以通过firewall-cmd --get-services来查看服务&#xff0c;也可以通过配置文件查看这些服务/var/lib/firewalld/ser…