【数据结构】线性表之《顺序表》超详细实现
顺序表
- 一.数据结构
- 1.逻辑结构
- 2.物理结构
- 二.顺序表的分类
- 1.静态顺序表
- 2.动态顺序表
- 三.顺序表的实现
- 1.创建顺序表
- 2.初始化顺序表
- 3.判断是否扩容
- 4.打印顺序表
- 5.插入操作
- 1.头插
- 2.尾插
- 3.按照下标插入
- 6.删除操作
- 1.头删
- 2.尾删
- 3.按照下标删除
- 7.查找数据
- 8.修改数据
- 9.清空顺序表
- 10.销毁顺序表
- 四.模块化源代码
- 1.SeqList.h
- 2.SeqList.c
- 3.test.c
- 五.顺序表必做OJ题
前言:相信大家在学完C语言后,对于指针
,结构体
以及动态内存管理
有了一定的见解,那么数据结构
像是检验真理的唯一标椎
,它考察了你掌握这三种语法的程度,如果掌握的不是很理想的友友们,建议看看鄙人主页总结的文章,好啦,数据结构之旅就正式开始啦。
一.数据结构
数据结构
:计算机存储、组织数据的方式
。数据结构是指相互之间存在一种或多种特定关系的数据元素的集合。数据结构反映数据的内部构成,即数据由那部分构成,以什么方式构成,以及数据元素之间呈现的结构。
1.逻辑结构
逻辑结构
:数据对象中数据元素之间的相互关系。
逻辑结构分为:集合结构,线性结构,树形结构和图形结构。
2.物理结构
物理结构
:数据的逻辑结构在计算机中的存储形式。
物理结构分为:顺序存储结构和链式存储结构。
二.顺序表的分类
顺序表
实际属于线性表
这个大家族,那么什么是线性表呢?
- 线性表:是n个具有相同特性的数据元素的有限序列。线性表是一种在实际中广泛使用的数据结构,常见的线性表:顺序表、链表、栈、队列、字符串…
- 线性表在逻辑上是线性结构,也就说是连续的一条直线。但是在物理结构上并不一定是连续的,
- 线性表在物理上存储时,通常以
数组
和链式
结构的形式存储。
1.静态顺序表
#define MAXSIZE 100 //静态顺序表的容量
typedef int SLDataType; //增强程序的可维护性typedef struct SeqList
{SLDataType arr[MAXSIZE];//定长数组int size; //有效的数据个数
}SeqList;
也许有人会问:这个静态顺序表说的这么神秘,本质上不就是一个数组吗?
答:没错,顺序表
的低层就是数组
,逻辑结构与物理结构都是连续的。不过顺序表对数组进行了封装,提供了大量常用的接口(所谓接口就是调用函数),方便完成数据进行增,删,查,改等一系列的操作。
静态顺序表的缺点:程序一但运行,数组的大小就确定了,不能被修改。数组大小给小了,空间就不够用;数组大小给大了,空间就白白的浪费掉了;
为了方便对静态顺序表进行扩容,于是,动态顺序表便应运而生。
2.动态顺序表
typedef int SLDataType;//增强程序的可维护性typedef struct SeqList
{SLDataType* arr; //动态的,可以扩容int size; //有效的数据个数int capacity; //容量
}SL;
动态顺序表:通过堆区的动态内存管理控制顺序表空间的大小,即容量。
以下介绍的是基于动态顺序表的实现。
三.顺序表的实现
1.创建顺序表
创建一个顺序表结构,包含指向这块空间的起始地址,顺序表中存储数据的个数以及顺序表的最大容量。
typedef int SLDataType;//增强程序的可维护性,改变数据类型,只需改变int即可typedef struct SeqList
{SLDataType* arr; //指向顺序表的起始位置,方便扩容int size; //顺序表的有效的数据个数int capacity; //顺序表的容量大小
}SL;//类型的重命名
//等价于typedef struct SeqList SL;
2.初始化顺序表
一般初始化我们都习惯赋值为0,指针赋值为NULL。
void SeqListInit(SL* ps)
{assert(ps);//断言操作,等价于assert(ps != NULL);ps->arr = NULL;ps->size = 0;ps->capacity = 0;
}
3.判断是否扩容
当我们想要增加数据的时候,会遇到容量不够用的问题。所以在此之前,应该检查容量与有效数据之间的关系,判断是否要扩容,接着插入数据。
void SeqListCheckCapacity(SL* ps)
{assert(ps);if (ps->size == ps->capacity)//顺序表已满,进行扩容操作{//判断顺序表容量是否为0,若为0,开辟储存4个数据大小的空间,若不为0,则容量翻倍int newcapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;//开辟空间SLDataType* tmp = (SLDataType*)realloc(ps->arr, newcapacity * sizeof(SLDataType));if (tmp == NULL)//开辟失败{perror("realloc fail!");exit(1);//强行退出程序(表示遇到异常情况)}ps->arr = tmp;//开辟成功,修改指针ps->capacity = newcapacity;//修改容量}
}
注意
:若传入realloc的指针为空指针(NULL),则realloc函数等价于malloc函数。
4.打印顺序表
循环遍历顺序表数据即可。
void SeqListPrint(SL* ps)
{assert(ps);for (int i = 0; i < ps->size; i++){printf("%d ", ps->arr[i]);}printf("\n");
}
5.插入操作
1.头插
头插的思想:将数据整体向后挪动一位。注意:为了防止覆盖原先的数据,采用从后向前挪动。再进行头部插入,最后有效数据个数+1。
void SeqListPushFront(SL* ps, SLDataType x)
{assert(ps);SeqListCheckCapacity(ps);//检查容量int end = ps->size;while (end > 0){ps->arr[end] = ps->arr[end - 1];//将数据整体向后挪动一位。end--;}ps->arr[0] = x;//头插ps->size++;//有效数据个数+1//等价于在下标为0处插入:SeqListInsert(ps, 0, x);
}
2.尾插
尾插的思想:直接在尾部插入,有效数据个数+1即可。
void SeqListPushBack(SL* ps, SLDataType x)
{assert(ps);SeqListCheckCapacity(ps);//检查容量ps->arr[ps->size++] = x;//尾插:采用后置++//等价于在下标为ps->size处插入:SeqListInsert(ps, ps->size, x);
}
3.按照下标插入
按照下标插入的思想:与头插的思想相同,只不过是要挪动数据的起始位置不同而已。
void SeqListInsert(SL* ps, int pos, SLDataType x)
{assert(ps);assert(pos >= 0 && pos <= ps->size);//判断下标的合法性SeqListCheckCapacity(ps);int end = ps->size;while (end > pos){ps->arr[end] = ps->arr[end - 1];end--;}ps->arr[pos] = x;ps->size++;
}
6.删除操作
1.头删
头删的思想:不是真正意义上的删除数据,而是将头部之后的数据整体向前挪动一位,覆盖头部数据,达到与头删相同的效果,最后有效数据个数-1。注意:为了防止覆盖原先的数据,采用从前向后挪动,这里与头插不同。
void SeqListPopFront(SL* ps)
{assert(ps);assert(ps->size > 0);//前提:顺序表存在数据int start = 0;while (start < ps->size - 1){ps->arr[start] = ps->arr[start + 1];start++;}ps->size--;//有效数据个数-1//等价于在下标为0处删除:SeqListErase(ps, 0);
}
2.尾删
尾删的思想:有效数据个数-1即可。
void SeqListPopBack(SL* ps)
{assert(ps);assert(ps->size > 0);//前提:顺序表存在数据ps->size--;//有效数据个数-1//等价于在下标为ps->size - 1处删除:SeqListErase(ps, ps->size - 1);
}
3.按照下标删除
按照下标删除的思想:与头删的思想相同,只不过是要挪动数据的起始位置不同而已。
void SeqListErase(SL* ps, int pos)
{assert(ps);assert(ps->size > 0);//前提:顺序表存在数据assert(pos >= 0 && pos < ps->size);//判断下标的合法性int start = pos;while (start < ps->size - 1){ps->arr[start] = ps->arr[start + 1];start++;}ps->size--;
}
7.查找数据
查找的思想:遍历数据,找到了返回下标,未找到返回-1即可。
int SeqListFind(SL* ps, SLDataType x)
{assert(ps);for (int i = 0; i < ps->size; i++){if (ps->arr[i] == x){return i;//找到该数据,返回下标}}return -1;//未找到,返回-1
}
8.修改数据
修改的思想:利用下标确定位置,直接修改就行。较为简单。
void SeqListModify(SL* ps, int pos, SLDataType x)
{assert(ps);assert(pos >= 0 && pos < ps->size);ps->arr[pos] = x;
}
9.清空顺序表
清空的思想:将有效数据个数与容量赋值为0。
void SeqListClear(SL* ps)
{assert(ps);ps->size = 0;ps->capacity = 0;
}
10.销毁顺序表
销毁的思想:由于空间是利用动态内存函数 realloc 在堆区开辟的,所以要及时释放,避免内存泄漏。
void SeqListDestory(SL* ps)
{assert(ps);if (ps->arr != NULL){free(ps->arr);}ps->arr = NULL;//置为NULL,防止野指针SeqListClear(ps);//清空顺序表
}
四.模块化源代码
1.SeqList.h
//#pragma once:防止头文件被重复包含
#ifndef __SEQLIST_H__
#define __SEQLIST_H__#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<assert.h>typedef int SLDataType;//增强程序的可维护性typedef struct SeqList
{SLDataType* arr; //动态的,可以扩容int size; //有效的数据个数int capacity; //容量
}SL;void SeqListInit(SL* ps);//顺序表初始化void SeqListCheckCapacity(SL* ps);//检查顺序表的容量void SeqListPrint(SL* ps);//打印顺序表void SeqListPushBack(SL* ps, SLDataType x);//顺序表尾部插入void SeqListPushFront(SL* ps, SLDataType x);//顺序表头部插入void SeqListPopBack(SL* ps);//顺序表尾部删除void SeqListPopFront(SL* ps);//顺序表头部删除void SeqListInsert(SL* ps, int pos, SLDataType x);//顺序表按照位置(下标)插入void SeqListErase(SL* ps, int pos);//顺序表按照位置(下标)删除int SeqListFind(SL* ps, SLDataType x);//顺序表查找元素值,返回下标void SeqListModify(SL* ps, int pos, SLDataType x);//顺序表按位置(下标)修改void SeqListClear(SL* ps);//清空顺序表void SeqListDestory(SL* ps);//销毁顺序表#endif
2.SeqList.c
#define _CRT_SECURE_NO_WARNINGS 1#include"SeqList.h"void SeqListInit(SL* ps)
{assert(ps);//等价于assert(ps != NULL);ps->arr = NULL;ps->size = 0;ps->capacity = 0;
}void SeqListCheckCapacity(SL* ps)
{assert(ps);if (ps->size == ps->capacity){int newcapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;SLDataType* tmp = (SLDataType*)realloc(ps->arr, newcapacity * sizeof(SLDataType));//扩容if (tmp == NULL){perror("realloc fail!");exit(1);//强行退出程序(表示遇到异常情况)}ps->arr = tmp;ps->capacity = newcapacity;}
}void SeqListPrint(SL* ps)
{assert(ps);for (int i = 0; i < ps->size; i++){printf("%d ", ps->arr[i]);}printf("\n");
}void SeqListPushBack(SL* ps, SLDataType x)
{assert(ps);SeqListCheckCapacity(ps);ps->arr[ps->size++] = x;//SeqListInsert(ps, ps->size, x);
}void SeqListPushFront(SL* ps, SLDataType x)
{assert(ps);SeqListCheckCapacity(ps);int end = ps->size;while (end > 0){ps->arr[end] = ps->arr[end - 1];end--;}ps->arr[0] = x;ps->size++;//SeqListInsert(ps, 0, x);
}void SeqListPopBack(SL* ps)
{assert(ps);assert(ps->size > 0);ps->size--;//SeqListErase(ps, ps->size - 1);
}void SeqListPopFront(SL* ps)
{assert(ps);assert(ps->size > 0);int start = 0;while (start < ps->size - 1){ps->arr[start] = ps->arr[start + 1];start++;}ps->size--;//SeqListErase(ps, 0);
}void SeqListInsert(SL* ps, int pos, SLDataType x)
{assert(ps);assert(pos >= 0 && pos <= ps->size);SeqListCheckCapacity(ps);int end = ps->size;while (end > pos){ps->arr[end] = ps->arr[end - 1];end--;}ps->arr[pos] = x;ps->size++;
}void SeqListErase(SL* ps, int pos)
{assert(ps);assert(ps->size > 0);assert(pos >= 0 && pos < ps->size);int start = pos;while (start < ps->size - 1){ps->arr[start] = ps->arr[start + 1];start++;}ps->size--;
}int SeqListFind(SL* ps, SLDataType x)
{assert(ps);for (int i = 0; i < ps->size; i++){if (ps->arr[i] == x){return i;}}return -1;
}void SeqListModify(SL* ps, int pos, SLDataType x)
{assert(ps);assert(pos >= 0 && pos < ps->size);ps->arr[pos] = x;
}void SeqListClear(SL* ps)
{assert(ps);ps->size = 0;ps->capacity = 0;
}void SeqListDestory(SL* ps)
{assert(ps);if (ps->arr != NULL){free(ps->arr);}ps->arr = NULL;SeqListClear(ps);
}
3.test.c
#define _CRT_SECURE_NO_WARNINGS 1#include"SeqList.h"enum//匿名枚举
{EXIT,PUSHBACK,PUSHFRONT,POPBACK,POPFRONT,INSERT,ERASE,FIND,MODIFY,PRINT,CLEAR
};void Menu()
{printf("*************顺序表************\n");printf("****1.尾插 2.头插****\n");printf("****3.尾删 4.头删****\n");printf("****5.插入 6.删除****\n");printf("****7.查找 8.修改****\n");printf("****9.打印 10.清空****\n");printf("****0.退出 ******\n");printf("*******************************\n");
}int main()
{SL sl;SeqListInit(&sl);int select = 0; //菜单选项SLDataType value; //插入的值int pos = 0; //插入或删除的下标do{Menu();printf("请选择您的操作:");scanf("%d", &select);switch (select){case EXIT:printf("退出顺序表!");break;case PUSHBACK:printf("请输入您要尾插的值(输入-1代表结束):");while ((scanf("%d", &value), value != -1)) //逗号表达式{SeqListPushBack(&sl, value);}break;case PUSHFRONT:printf("请输入您要头插的值(输入-1代表结束):");do{scanf("%d", &value);if (value != -1){SeqListPushFront(&sl, value);}} while (value != -1);break;case POPBACK:SeqListPopBack(&sl);break;case POPFRONT:SeqListPopFront(&sl);break;case INSERT:printf("请输入要插入的《下标》与《值》:");scanf("%d %d", &pos, &value);SeqListInsert(&sl, pos, value);break;case ERASE:printf("请输入要删除的《下标》:");scanf("%d", &pos);SeqListErase(&sl, pos);break;case FIND:printf("请输入要查找的《值》:");scanf("%d", &value);int ret = SeqListFind(&sl, value);if (ret != -1){printf("找到了下标为:%d\n", ret);}else{printf("找不到!");}break;case MODIFY:printf("请输入要修改的《下标》以及修改后的《值》:");scanf("%d %d", &pos, &value);SeqListModify(&sl, pos, value);break;case PRINT:SeqListPrint(&sl);break;case CLEAR:SeqListClear(&sl);break;default:printf("您输入的值错误,请重新选择!\n");break;}} while (select);SeqListDestory(&sl);return 0;
}
五.顺序表必做OJ题
- 原地移除元素
- 合并两个有序数组
创作不易,如果能帮到你的话能赏个三连吗?感谢啦!!!
相关文章:
【数据结构】线性表之《顺序表》超详细实现
顺序表 一.数据结构1.逻辑结构2.物理结构 二.顺序表的分类1.静态顺序表2.动态顺序表 三.顺序表的实现1.创建顺序表2.初始化顺序表3.判断是否扩容4.打印顺序表5.插入操作1.头插2.尾插3.按照下标插入 6.删除操作1.头删2.尾删3.按照下标删除 7.查找数据8.修改数据9.清空顺序表10.销…...
开源模型应用落地-音乐生成模型-suno/bark深度使用-AIGC应用探索(六)
一、前言 学习音乐生成模型具有极其重要的价值。通过对音乐生成模型的深入学习,我们能够探索到音乐创作的全新边界和可能性。它不仅可以开启一扇通往无限音乐创意的大门,让我们领略到科技与艺术完美融合所带来的震撼与惊喜,还能帮助我们在音乐领域实现前所未有的突破和创新。…...

为何选择Xinstall?告别邀请码,让App推广更便捷!
在互联网日益繁荣的今天,App的推广和运营成为了各大企业关注的重点。然而,传统的推广方式如邀请码限制,往往会给用户带来不便,同时也限制了App的快速增长。在这个背景下,Xinstall凭借其独特的功能和服务,成…...

JavaScript基础入门
目录 任务描述 相关知识 JavaScript语言简介 JavaScript注释 搭建JavaScript的运行环境 JavaScript输出 弹出对话框模式 控制台模式 页面输出模式 编程要求 任务描述 要了解一门编程语言,要从输出开始。 本关任务:采用相关知识中介绍的任意一…...

windows11子系统Ubuntu 22.04.4子安装图形化界面
1、windows11家庭版本设置 打开虚拟机安装许可 2、Microsoft Store下载安装ubuntu 我使用的是22.04.4 LTS版本 3、 打开ubuntu 命令窗口 1、打开win11的命令行,在下拉三角下标,打开,可以看到有Ubuntu 的选项,点击即可进入linux命…...

对 2024 年美赛选题的建议
对2024年美赛选题的建议包括: 1. 深入探讨当下全球面临的重大问题和挑战:鉴于美赛通常聚焦于全球性议题,如气候变化、可持续发展、数据分析等,参赛学生应关注这些议题,并深入研究相关数据与背景信息,以提出…...
PyTorch tutorials:快速学会使用PyTorch
准备深入学习transformer,并参考一些资料和论文实现一个大语言模型,顺便做一个教程,今天是番外篇,介绍下PyTorch,后面章节实现代码主要使用这个框架。 本系列禁止转载,主要是为了有不同见解的同学可以方便联…...

【CT】LeetCode手撕—手撕快排
目录 题目1-思路-快排1-1 快排的核心思想快速排序算法步骤优美的调整区间 1-2 ⭐快排的实现 2- 实现⭐912. 排序数组——题解思路 3- ACM 实现 题目 原题连接:912. 排序数组 1-思路-快排 1-1 快排的核心思想 选择一个基准 基准左侧的元素都小于该元素基准右侧的元…...

使用ARK工具ATool清除典型蠕虫MyDoom
1 概述 在长期的日常安全事件监测过程中,安天CERT经常捕获到大量的MyDoom蠕虫样本和传播该蠕虫的钓鱼邮件。受害主机感染MyDoom后会被放置后门,以便攻击者下发后续恶意软件,进行攻击或窃密等操作。MyDoom蠕虫最早发现于2004年&…...

在hue中使用ooize调度ssh任务无法执行成功,无法查看错误
ssh执行失败,但是hue没有给出明确的错误原因: 经过经验分析,原来是服务器上的sh文件用的是doc/window格式,需要使用notepad将格式改为unix之后就可以正常执行。 特此记录,避免遗忘知识点...

一套轻量、安全的问卷系统基座,提供面向个人和企业的一站式产品级解决方案
大家好,今天给大家分享的是一款轻量、安全的问卷系统基座。 XIAOJUSURVEY是一套轻量、安全的问卷系统基座,提供面向个人和企业的一站式产品级解决方案,快速满足各类线上调研场景。 内部系统已沉淀 40种题型,累积精选模板 100&a…...

3秒生成!这个AI模型画风也太治愈了,新手也能轻松驾驭
还在为不会画画而苦恼吗?别担心,今天给大家介绍一个超好用的AI模型——Soft and Squishy Linework,即使是小白也能轻松生成可爱的动漫图像! Soft and Squishy Linework:专门生成柔和的、低保真(lofi&#…...

数字人全拆解:如何构建一个基于大模型的实时对话3D数字人?
简单地说,数字人就是在数字世界的“人”。当前语境下我们谈到的数字人通常指的是借助AI技术驱动的虚拟世界人物,具备与真实人类相似甚至接近的外形、感知、交互与行为能力。 AI技术在智能数字人的应用中举足轻重,特别是随着大模型能力的涌现…...

实战 | 基于YOLOv10的车辆追踪与测速实战【附源码+步骤详解】
《博主简介》 小伙伴们好,我是阿旭。专注于人工智能、AIGC、python、计算机视觉相关分享研究。 ✌更多学习资源,可关注公-仲-hao:【阿旭算法与机器学习】,共同学习交流~ 👍感谢小伙伴们点赞、关注! 《------往期经典推…...

2024北京智源大会
北京智源大会是年度国际性人工智能高端学术交流的盛会,定位于内行的AI盛会。智源大会紧密围绕当前人工智能学术领域迫切需要解决的问题,以及产业落地过程中存在的诸多挑战,开展深入探讨。智源研究院是2018年11月份成立的一家人工智能领域的新…...

youlai-boot项目的学习—本地数据库安装与配置
数据库脚本 在项目代码的路径下,有两个版本的mysql数据库脚本,使用对应的脚本就安装对应的数据库版本,本文件选择了5 数据库安装 这里在iterm2下使用homebrew安装mysql5 brew install mysql5.7注:记得配置端终下的科学上网&a…...

Android平台如何实现多路低延迟RTSP|RTMP播放?
技术背景 实际上,我们在2015年做Android平台RTSP、RTMP播放模块的时候,第一版就支持了多实例播放,因为SDK设计比较灵活,做个简单的player实例封装即可实现多实例播放(Android Unity的就有多路demo)&#x…...

深入探索Java开发世界:Java基础~类型分析大揭秘
文章目录 一、基本数据类型二、封装类型三、类型转换四、集合类型五、并发类型 Java基础知识,类型知识点梳理~ 一、基本数据类型 Java的基本数据类型是语言的基础,它们直接存储在栈内存中,具有固定的大小和不变的行为。 八种基本数据类型的具…...

短URL服务设计
引言 在营销系统里,为了增加系统的活跃用户数,经常会有各种各样的营销活动。这类活动几乎都是为了充分利用存量用户的价值,促使他们分享产品或App以达到触达到更多用户的目的。又或者是出于营销目的,群发优惠券触达短信这种场景。…...

Kafka集成flume
1.flume作为生产者集成Kafka kafka作为flume的sink,扮演消费者角色 1.1 flume配置文件 vim $kafka/jobs/flume-kafka.conf # agent a1.sources r1 a1.sinks k1 a1.channels c1 c2# Describe/configure the source a1.sources.r1.type TAILDIR #记录最后监控文件…...

UE5 学习系列(二)用户操作界面及介绍
这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…...

边缘计算医疗风险自查APP开发方案
核心目标:在便携设备(智能手表/家用检测仪)部署轻量化疾病预测模型,实现低延迟、隐私安全的实时健康风险评估。 一、技术架构设计 #mermaid-svg-iuNaeeLK2YoFKfao {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg…...
CMake控制VS2022项目文件分组
我们可以通过 CMake 控制源文件的组织结构,使它们在 VS 解决方案资源管理器中以“组”(Filter)的形式进行分类展示。 🎯 目标 通过 CMake 脚本将 .cpp、.h 等源文件分组显示在 Visual Studio 2022 的解决方案资源管理器中。 ✅ 支持的方法汇总(共4种) 方法描述是否推荐…...
Python 包管理器 uv 介绍
Python 包管理器 uv 全面介绍 uv 是由 Astral(热门工具 Ruff 的开发者)推出的下一代高性能 Python 包管理器和构建工具,用 Rust 编写。它旨在解决传统工具(如 pip、virtualenv、pip-tools)的性能瓶颈,同时…...

人工智能(大型语言模型 LLMs)对不同学科的影响以及由此产生的新学习方式
今天是关于AI如何在教学中增强学生的学习体验,我把重要信息标红了。人文学科的价值被低估了 ⬇️ 转型与必要性 人工智能正在深刻地改变教育,这并非炒作,而是已经发生的巨大变革。教育机构和教育者不能忽视它,试图简单地禁止学生使…...
JavaScript基础-API 和 Web API
在学习JavaScript的过程中,理解API(应用程序接口)和Web API的概念及其应用是非常重要的。这些工具极大地扩展了JavaScript的功能,使得开发者能够创建出功能丰富、交互性强的Web应用程序。本文将深入探讨JavaScript中的API与Web AP…...

【C++进阶篇】智能指针
C内存管理终极指南:智能指针从入门到源码剖析 一. 智能指针1.1 auto_ptr1.2 unique_ptr1.3 shared_ptr1.4 make_shared 二. 原理三. shared_ptr循环引用问题三. 线程安全问题四. 内存泄漏4.1 什么是内存泄漏4.2 危害4.3 避免内存泄漏 五. 最后 一. 智能指针 智能指…...

逻辑回归暴力训练预测金融欺诈
简述 「使用逻辑回归暴力预测金融欺诈,并不断增加特征维度持续测试」的做法,体现了一种逐步建模与迭代验证的实验思路,在金融欺诈检测中非常有价值,本文作为一篇回顾性记录了早年间公司给某行做反欺诈预测用到的技术和思路。百度…...

MacOS下Homebrew国内镜像加速指南(2025最新国内镜像加速)
macos brew国内镜像加速方法 brew install 加速formula.jws.json下载慢加速 🍺 最新版brew安装慢到怀疑人生?别怕,教你轻松起飞! 最近Homebrew更新至最新版,每次执行 brew 命令时都会自动从官方地址 https://formulae.…...

通过 Ansible 在 Windows 2022 上安装 IIS Web 服务器
拓扑结构 这是一个用于通过 Ansible 部署 IIS Web 服务器的实验室拓扑。 前提条件: 在被管理的节点上安装WinRm 准备一张自签名的证书 开放防火墙入站tcp 5985 5986端口 准备自签名证书 PS C:\Users\azureuser> $cert New-SelfSignedCertificate -DnsName &…...