当前位置: 首页 > news >正文

数据结构小扫尾——栈

数据结构小扫尾——栈

@jarringslee

文章目录

  • 数据结构小扫尾——栈
    • 栈本质上是一种特殊的线性表。
      • (一)线性表的定义
      • (二)线性表的运算
    • 什么是栈。
      • (一)栈的定义
      • (二)栈的分类
      • (三)栈的存储结构
      • (四)栈的示例
    • 二、栈的实现
      • (一)顺序栈的实现
      • (二)链栈的实现
    • 栈的应用
      • (一)括号匹配
      • (二)中缀表达式转后缀表达式
    • 例题
      • [20. 有效的括号 - 力扣(LeetCode)](https://leetcode.cn/problems/valid-parentheses/)
      • [150. 逆波兰表达式求值 - 力扣(LeetCode)](https://leetcode.cn/problems/evaluate-reverse-polish-notation/)

​ 栈stack作为一种重要的数据结构,在实际开发中有着广泛的应用,如函数调用、表达式求值等。

栈本质上是一种特殊的线性表。

(一)线性表的定义

线性表是一种最基础的数据结构,它由具有相同特性的数据元素构成,这些数据元素之间存在着线性关系,即第一个元素称为表头,最后一个元素称为表尾,除第一个元素外,每个元素有且只有一个前驱,除最后一个元素外,每个元素有且只有一个后继。线性表可以顺序存储,也可以链式存储。

(二)线性表的运算

1. **插入** :在表中指定位置插入一个元素。
2. **删除** :删除表中指定位置的元素。
3. **查找** :查找表中满足特定条件的元素。

什么是栈。

(一)栈的定义

栈是一种特殊的线性表,它满足后进先出的特性,即最后被插入的元素最先被删除。栈的插入和删除操作都只能在栈顶进行。

就像一个桶。我们把东西按顺序放进去,最后一个就放在了桶的最顶端。我们需要拿出来的时候,先拿出来最后放进去的,最后拿出来第一个放进去的。起到了一个逆序的过程。

(二)栈的分类

  • 顺序栈 :使用数组实现的栈,元素在数组中连续存储。
  • 链栈 :使用链表实现的栈,元素通过指针链接在一起。

(三)栈的存储结构

栈通常使用顺序栈和链栈来存储。顺序栈的存储结构如下:

typedef int DataType;
typedef struct Stack {DataType* a; //存放栈元素的数组int top;     //栈顶指针int capacity; //栈的最大容量
} Stack;

链栈的存储结构如下:

typedef int DataType;
typedef struct Node {DataType data;struct Node* next;
} Node;typedef struct LinkStack {Node* top; //栈顶指针
} LinkStack;

(四)栈的示例

假设我们有一个顺序栈 [1, 2, 3, 4, 5],其中 5 是栈顶元素。当插入元素 6 时,栈变为 [1, 2, 3, 4, 5, 6]。当删除元素时,栈变为 [1, 2, 3, 4, 5]。

二、栈的实现

(一)顺序栈的实现

#include <stdlib.h>
#include <stdio.h>
#include <assert.h>// 定义栈中存储的数据类型为整型
typedef int DataType;// 定义顺序栈的结构体,包含存储元素的数组、栈顶指针和栈的最大容量
typedef struct Stack {DataType* a; // 存放栈元素的数组int top;     // 栈顶指针,初始值为 -1 表示栈为空int capacity; // 栈的最大容量
} Stack;// 栈的初始化函数
void StackInit(Stack* pstack) {assert(pstack); // 断言确保传入的指针非空pstack->a = (DataType*)malloc(sizeof(DataType) * 4); // 分配初始大小为 4 的动态数组if (pstack->a == NULL) { // 判断内存分配是否成功perror("malloc fail"); // 若分配失败,输出错误信息return;}pstack->top = -1; // 栈顶指针初始化为 -1pstack->capacity = 4; // 栈的初始容量设为 4
}// 栈的销毁函数
void StackDestroy(Stack* pstack) {assert(pstack); // 断言确保传入的指针非空free(pstack->a); // 释放动态分配的数组内存pstack->a = NULL; // 将数组指针置为空,避免野指针pstack->top = -1; // 栈顶指针重置为 -1pstack->capacity = 0; // 栈的容量重置为 0
}// 栈的插入(压栈)操作
void StackPush(Stack* pstack, DataType x) {assert(pstack); // 断言确保传入的指针非空// 判断栈是否已满,若栈满则扩容if (pstack->top == pstack->capacity - 1) {DataType* tmp = (DataType*)realloc(pstack->a, sizeof(DataType) * pstack->capacity * 2);if (tmp == NULL) { // 判断内存重新分配是否成功perror("realloc fail"); // 若扩容失败,输出错误信息return;}pstack->a = tmp; // 更新数组指针pstack->capacity *= 2; // 栈的容量翻倍}pstack->a[++pstack->top] = x; // 栈顶指针增 1 后存入新元素
}// 栈的删除(弹栈)操作
void StackPop(Stack* pstack) {assert(pstack); // 断言确保传入的指针非空assert(!StackEmpty(pstack)); // 断言确保栈不为空,防止溢出pstack->top--; // 栈顶指针减 1,实现元素出栈
}// 判断栈是否为空的函数
bool StackEmpty(Stack* pstack) {assert(pstack); // 断言确保传入的指针非空return pstack->top == -1; // 若栈顶指针为 -1 则栈为空,返回 true,否则返回 false
}// 获取栈顶元素的函数
DataType StackTop(Stack* pstack) {assert(pstack); // 断言确保传入的指针非空assert(!StackEmpty(pstack)); // 断言确保栈不为空,防止访问越界return pstack->a[pstack->top]; // 返回栈顶元素的值
}// 获取栈中元素个数的函数
int StackSize(Stack* pstack) {assert(pstack); // 断言确保传入的指针非空return pstack->top + 1; // 栈顶指针加 1 即为栈中元素个数
}

(二)链栈的实现

// 定义栈中存储的数据类型为整型
typedef int DataType;// 定义链栈节点的结构体,包含存储的数据和指向下一个节点的指针
typedef struct Node {DataType data; // 节点存储的数据struct Node* next; // 指向下一个节点的指针
} Node;// 定义链栈的结构体,包含指向栈顶的指针
typedef struct LinkStack {Node* top; // 栈顶指针,初始值为 NULL 表示栈为空
} LinkStack;// 链栈的初始化函数
void LinkStackInit(LinkStack* pstack) {assert(pstack); // 断言确保传入的指针非空pstack->top = NULL; // 栈顶指针初始化为空
}// 链栈的销毁函数
void LinkStackDestroy(LinkStack* pstack) {assert(pstack); // 断言确保传入的指针非空Node* cur = pstack->top; // 从栈顶开始遍历while (cur) { // 遍历链栈中的每个节点Node* next = cur->next; // 保存下一个节点的地址free(cur); // 释放当前节点的内存cur = next; // 移动到下一个节点}pstack->top = NULL; // 销毁后栈顶指针置为空
}// 链栈的插入(压栈)操作
void LinkStackPush(LinkStack* pstack, DataType x) {assert(pstack); // 断言确保传入的指针非空Node* new_node = (Node*)malloc(sizeof(Node)); // 动态分配新节点内存if (new_node == NULL) { // 判断内存分配是否成功perror("malloc fail"); // 若分配失败,输出错误信息return;}new_node->data = x; // 将数据存入新节点new_node->next = pstack->top; // 新节点的 next 指针指向原栈顶pstack->top = new_node; // 更新栈顶指针为新节点
}// 链栈的删除(弹栈)操作
void LinkStackPop(LinkStack* pstack) {assert(pstack); // 断言确保传入的指针非空assert(!LinkStackEmpty(pstack)); // 断言确保栈不为空,防止溢出Node* tmp = pstack->top; // 保存当前栈顶节点pstack->top = pstack->top->next; // 更新栈顶指针为下一个节点free(tmp); // 释放原栈顶节点内存
}// 判断链栈是否为空的函数
bool LinkStackEmpty(LinkStack* pstack) {assert(pstack); // 断言确保传入的指针非空return pstack->top == NULL; // 若栈顶指针为空则栈为空,返回 true,否则返回 false
}// 获取链栈栈顶元素的函数
DataType LinkStackTop(LinkStack* pstack) {assert(pstack); // 断言确保传入的指针非空assert(!LinkStackEmpty(pstack)); // 断言确保栈不为空,防止访问越界return pstack->top->data; // 返回栈顶元素的值
}// 获取链栈中元素个数的函数
int LinkStackSize(LinkStack* pstack) {assert(pstack); // 断言确保传入的指针非空int size = 0; // 初始化计数器为 0Node* cur = pstack->top; // 从栈顶开始遍历while (cur) { // 遍历链栈中的每个节点size++; // 每遍历一个节点计数器加 1cur = cur->next; // 移动到下一个节点}return size; // 返回链栈中元素的总个数
}

栈的应用

(一)括号匹配

括号匹配是一种经典的栈应用,用于检查表达式中的括号是否正确匹配。

// 判断括号匹配的函数
bool isValid(char* s) {Stack stack; // 定义一个顺序栈StackInit(&stack); // 初始化栈for (int i = 0; s[i] != '\0'; i++) { // 遍历字符串中的每个字符if (s[i] == '(' || s[i] == '[' || s[i] == '{') { // 若字符为左括号StackPush(&stack, s[i]); // 将左括号压入栈中} else { // 若字符为右括号if (StackEmpty(&stack)) { // 判断栈是否为空,若为空说明没有匹配的左括号StackDestroy(&stack); // 销毁栈以释放资源return false; // 返回不匹配的结果}char top = StackTop(&stack); // 取出栈顶元素(最近的左括号)StackPop(&stack); // 将栈顶元素弹出// 判断右括号与左括号是否匹配if ((s[i] == ')' && top != '(') || (s[i] == ']' && top != '[') || (s[i] == '}' && top != '{')) {StackDestroy(&stack); // 销毁栈以释放资源return false; // 若不匹配,返回不匹配的结果}}}bool result = StackEmpty(&stack); // 若遍历结束栈为空,则所有括号匹配;否则存在未匹配的左括号StackDestroy(&stack); // 销毁栈以释放资源return result; // 返回判断结果
}

(二)中缀表达式转后缀表达式

中缀表达式转后缀表达式是另一种经典的栈应用。

// 判断字符是否为运算符的辅助函数
bool isOperator(char c) {return c == '+' || c == '-' || c == '*' || c == '/'; // 若字符是其中之一,则返回 true 表示是运算符
}// 获取运算符优先级的辅助函数
int precedence(char op) {if (op == '+' || op == '-') { // 加减运算符优先级较低,返回 1return 1;} else if (op == '*' || op == '/') { // 乘除运算符优先级较高,返回 2return 2;} else { // 其他字符不是运算符,返回 0return 0;}
}// 中缀表达式转后缀表达式的函数
void infixToPostfix(char* infix, char* postfix) {Stack stack; // 定义一个顺序栈StackInit(&stack); // 初始化栈int j = 0; // 用于记录后缀表达式中字符的位置for (int i = 0; infix[i] != '\0'; i++) { // 遍历中缀表达式的每个字符if (infix[i] == '(') { // 若遇到左括号,直接压栈StackPush(&stack, infix[i]);} else if (infix[i] == ')') { // 若遇到右括号// 依次弹出栈中的运算符直到遇到左括号,并将弹出的运算符加入后缀表达式while (!StackEmpty(&stack) && StackTop(&stack) != '(') {postfix[j++] = StackTop(&stack);StackPop(&stack);}StackPop(&stack); // 弹出左括号,但不加入后缀表达式} else if (isOperator(infix[i])) { // 若遇到运算符// 将栈中优先级大于等于当前运算符的运算符依次弹出并加入后缀表达式while (!StackEmpty(&stack) && precedence(infix[i]) <= precedence(StackTop(&stack))) {postfix[j++] = StackTop(&stack);StackPop(&stack);}StackPush(&stack, infix[i]); // 将当前运算符压栈} else { // 若是操作数,直接加入后缀表达式postfix[j++] = infix[i];}}// 弹出栈中剩余的运算符并加入后缀表达式while (!StackEmpty(&stack)) {postfix[j++] = StackTop(&stack);StackPop(&stack);}postfix[j] = '\0'; // 在后缀表达式末尾添加字符串结束标志StackDestroy(&stack); // 销毁栈以释放资源
}

例题

20. 有效的括号 - 力扣(LeetCode)

给定一个只包含三种括号字符 '('')''{''}''['']' 的字符串 s,判断 s 是否是有效的括号字符串。

示例 1:

输入:s = "()"
输出:true

示例 2:

输入:s = "()[]{}"
输出:true

示例 3:

输入:s = "(]"
输出:false

​ 我们首先初始化一个空栈,然后遍历字符串中的每一个字符。如果字符串是左括号,则压入栈。如果字符是右括号,则检查栈顶元素是否匹配,匹配则弹栈,否则返回 false。如果字符是右括号,则检查栈顶元素是否匹配,匹配则弹栈,否则返回 false

// 判断括号匹配的函数(与前面的 isValid 函数一致)
bool isValid(char* s) {Stack stack;StackInit(&stack);for (int i = 0; s[i] != '\0'; i++) {if (s[i] == '(' || s[i] == '[' || s[i] == '{') {StackPush(&stack, s[i]);} else {if (StackEmpty(&stack)) {StackDestroy(&stack);return false;}char top = StackTop(&stack);StackPop(&stack);if ((s[i] == ')' && top != '(') || (s[i] == ']' && top != '[') || (s[i] == '}' && top != '{')) {StackDestroy(&stack);return false;}}}bool result = StackEmpty(&stack);StackDestroy(&stack);return result;
}

150. 逆波兰表达式求值 - 力扣(LeetCode)

根据逆波兰表示法,求表达式的值。

有效的算符包括 +-*/。每个运算对象可以是整数,也可以是另一个逆波兰表达式。

示例 1:

输入:tokens = ["2","1","+","3","*"]
输出:9
解释:该算式转化为常见的中缀逆波兰表达式为:((2 + 1) * 3) = 9

示例 2:

输入:tokens = ["4","13","5","/","+"]
输出:6
解释:该算式转化为常见的中缀逆波兰表达式为:(4 + (13 / 5)) = 6

​ 依旧是初始化一个空栈,然后遍历逆波兰表达式。如果元素是数字,则压入栈。如果元素是运算符,则弹出栈顶的两个数字进行运算,将结果压入栈。最后栈顶元素即为结果。

// 逆波兰表达式求值的函数
int evalRPN(char** tokens, int tokensSize) {Stack stack;StackInit(&stack);for (int i = 0; i < tokensSize; i++) { // 遍历逆波兰表达式的每个标记char* token = tokens[i];// 判断是否为运算符if (strcmp(token, "+") == 0) {assert(!StackEmpty(&stack)); // 确保栈中有足够的操作数int b = StackTop(&stack); // 取出栈顶元素作为第二个操作数StackPop(&stack);int a = StackTop(&stack); // 取出下一个栈顶元素作为第一个操作数StackPop(&stack);StackPush(&stack, a + b); // 将运算结果压栈} else if (strcmp(token, "-") == 0) {assert(!StackEmpty(&stack));int b = StackTop(&stack);StackPop(&stack);int a = StackTop(&stack);StackPop(&stack);StackPush(&stack, a - b);} else if (strcmp(token, "*") == 0) {assert(!StackEmpty(&stack));int b = StackTop(&stack);StackPop(&stack);int a = StackTop(&stack);StackPop(&stack);StackPush(&stack, a * b);} else if (strcmp(token, "/") == 0) {assert(!StackEmpty(&stack));int b = StackTop(&stack);StackPop(&stack);int a = StackTop(&stack);StackPop(&stack);StackPush(&stack, a / b);} else { // 若是操作数,则转换为整型后压栈StackPush(&stack, atoi(token));}}int result = StackTop(&stack); // 最终结果位于栈顶StackDestroy(&stack);return result;
}

相关文章:

数据结构小扫尾——栈

数据结构小扫尾——栈 jarringslee 文章目录 数据结构小扫尾——栈栈本质上是一种特殊的线性表。&#xff08;一&#xff09;线性表的定义&#xff08;二&#xff09;线性表的运算 什么是栈。&#xff08;一&#xff09;栈的定义&#xff08;二&#xff09;栈的分类&#xff0…...

策略模式(Strategy Pattern)

&#x1f9e0; 策略模式&#xff08;Strategy Pattern&#xff09; 策略模式是一种行为型设计模式&#xff0c;它允许定义一系列的算法或行为&#xff0c;然后将每个算法封装到一个类中&#xff0c;使得它们可以互换。策略模式让算法独立于使用它的客户端进行变化&#xff0c;…...

Qwen2_5-Omni-3B:支持视频、音频、图像和文本的全能AI,可在本地运行

Qwen2.5-Omni-3B是阿里云推出的全能AI模型。它能同时处理视频、音频、图像和文本。只有3B参数,却能在本地运行强大的多模态功能。 近日,已经在Hugging Face上发布。它是小型多模态AI系统的重要突破。 特点 Qwen2.5-Omni-3B与普通语言模型不同。它是真正的多模态系统,可以同…...

GZIPOutputStream 类详解

GZIPOutputStream 类详解 GZIPOutputStream 是 Java 中用于压缩数据为 GZIP 格式的输出流类&#xff0c;属于 java.util.zip 包。它是 DeflaterOutputStream 的子类&#xff0c;专门生成符合 GZIP 格式&#xff08;.gz 文件&#xff09;的压缩数据。 1. 核心功能 将数据压缩为…...

sudo useradd -r -s /bin/false -U -m -d /usr/share/ollama ollama解释这行代码的含义

这行命令用于为 OLLAMA 服务创建专用的系统用户&#xff0c;具体参数解析如下&#xff1a; sudo 以管理员权限执行命令&#xff0c;确保有足够权限创建系统用户。 useradd Linux 用户创建命令&#xff0c;用于在系统中新增用户。 -r 创建系统账户&#xff08;非登录用户&…...

自注意力(Self-Attention)和位置编码

自注意力 给定序列 x 1 , … , x n \mathbf{x}_1, \ldots, \mathbf{x}_n x1​,…,xn​, ∀ x i ∈ R d \forall \mathbf{x}_i \in \mathbb{R}^d ∀xi​∈Rd 自注意力池化层将 x i \mathbf{x}_i xi​ 当做key, value, query来对序列抽取特征得到 y 1 , … , y n \mathbf{y}…...

Linux压缩和解压类

一、gzip/gunzip 压缩 1、基本语法 gzip 文件 &#xff08;功能描述&#xff1a;压缩文件&#xff0c;只能将文件压缩为*.gz文件&#xff09; gunzip 文件.gz &#xff08;功能描述&#xff1a;解压缩文件命令&#xff09; 2、经验技巧 &#xff08;1&#…...

Kubernetes控制平面组件:Controller Manager详解

云原生学习路线导航页&#xff08;持续更新中&#xff09; kubernetes学习系列快捷链接 Kubernetes架构原则和对象设计&#xff08;一&#xff09;Kubernetes架构原则和对象设计&#xff08;二&#xff09;Kubernetes架构原则和对象设计&#xff08;三&#xff09;Kubernetes控…...

使用 JavaScript 实现数据导出为 Excel 和 CSV 文件

在 Web 开发中&#xff0c;经常会遇到需要将数据导出为文件的需求&#xff0c;例如将数据导出为 Excel 或 CSV 文件。今天&#xff0c;我们就来探讨如何使用 JavaScript 实现这一功能。 一、实现思路 我们通过 HTML 创建一个按钮&#xff0c;点击按钮时&#xff0c;触发 Java…...

设一个测试情境,新用户注册后显示的名字不完整,测试思路是怎么样的?

问题分析:新用户注册后显示名称不完整 典型表现:用户注册时输入"张三丰",系统仅显示"张"或"张三"等不完整信息 一、测试排查思维导图 二、详细测试方案 1. 前端测试 输入验证: 测试不同长度名称(1字符/10字符/50字符) 测试含空格名称(如…...

NHANES指标推荐:ZJU index

文章题目&#xff1a;Association between ZJU index and gallstones in US adult: a cross-sectional study of NHANES 2017-2020 DOI&#xff1a;10.1186/s12876-024-03553-9 中文标题&#xff1a;ZJU指数与美国成年人胆结石的关联&#xff1a;2017-2020年NHANES横断面研究 发…...

数据存储——高级存储之PV和PVC

一、概述 PV &#xff08; Persistent Volume &#xff09;是持久化卷的意思&#xff0c;是对底层的共享存储的一种抽象。一般情况下 PV 由 kubernetes 管理员进行创建和配置&#xff0c;它与底层具体的共享存储技术有关&#xff0c;并通过插件完成与共享存储的对接。 PVC &a…...

Astro Canvas 数据中心→设备一览大屏操作指南

✅ Astro Canvas 数据中心→设备一览大屏操作指南 📌 目标 通过API连接器 → 转换器 → 数据源 → 数据集 → Astro大屏设计,展示从 IoTDA 获取的设备影子数据,并在 Astro 大屏中以设备一览形式可视化展示(如设备ID、温度、湿度、烟雾浓度等状态)。 🔁 一、整体流程概…...

Cisco NDO - Nexus Dashboard Orchestrator

目录 一、什么是 Cisco NDO? 二、ND vs. NDO? 三、NDO vs. NDFC 四、NDO 用例: 一、什么是 Cisco NDO? Nexus Dashboard Orchestrator(NDO)可通过单一界面,实现跨多个数据中心的一致性网络与策略编排、可扩展性与灾难恢复等。 当在本地、多种私有云或公有云中同时运…...

Android 控件CalendarView、TextClock用法

一 UI代码 <?xml version="1.0" encoding="utf-8"?> <androidx.coordinatorlayout.widget.CoordinatorLayoutxmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto…...

Socket 编程 TCP

Socket 编程 TCP TCP socket API 详解V1 - Echo ServerV2 - Echo Server 多进程版本V3 - Echo Server 多线程版本V4 - Echo Server 线程池版本多线程远程命令执行v5 引入线程池版本翻译 TCP socket API 详解 socket(): socket()打开一个网络通讯端口,如果成功的话,就像 open…...

信息系统项目管理师-软考高级(软考高项)​​​​​​​​​​​2025最新(七)

个人笔记整理---仅供参考 项目立项管理 7.1项目建议与立项申请 项目建议书内容必背&#xff01; 7.2项目可行性研究 项目可行性研究必考 7.3项目的评估与决策...

Qt中的UIC

Qt中的UIC(User Interface Compiler, 用户界面编译器)&#xff1a;读取由Qt Widgets Designer生成的XML格式(.ui)文件并创建相应的C头文件或Python源文件。如将mainwindow.ui文件生成ui_mainwindow.h。 uic.exe位置在6.8.0\msvc2019_64\bin &#xff0c;其支持的输入参数如下所…...

【MATLAB例程】基于RSSI原理的Wi-Fi定位程序,N个锚点(数量可自适应)、三维空间,轨迹使用UKF进行滤波,附代码下载链接

本文所述程序实现了一种基于信号强度&#xff08;RSSI&#xff09;的Wi-Fi定位算法&#xff0c;并结合无迹卡尔曼滤波&#xff08;UKF&#xff09;对动态目标轨迹进行滤波优化。代码支持自适应锚点数量&#xff0c;适用于三维空间定位&#xff0c;可模拟目标运动、信号噪声及非…...

vulkanscenegraph显示倾斜模型(6.5)-vsg::DatabasePager

前言 上章深入分析了帧循环过程中&#xff0c;多线程下的记录与提交机制。本章将分析vsg::DatabasePager在更新场景图过程中的作用&#xff0c;进一步揭露vsg中场景图管理机制&#xff0c;并通过分析代码&#xff0c;详细解释vsg中场景图管理机制中的节点添加、节点删除、节点加…...

利用 Python pyttsx3实现文字转语音(TTS)

今天&#xff0c;我想跟大家分享如何利用 Python 编程语言&#xff0c;来实现文字转换为语音的功能&#xff0c;也就是我们常说的 Text-to-Speech (TTS) 技术。 你可能会好奇&#xff0c;为什么学习这个&#xff1f;想象一下&#xff0c;如果你想把书本、文章、杂志的内容转换…...

【PostgreSQL数据分析实战:从数据清洗到可视化全流程】5.1 描述性统计分析(均值/方差/分位数计算)

&#x1f449; 点击关注不迷路 &#x1f449; 点击关注不迷路 &#x1f449; 点击关注不迷路 文章大纲 5.1 描述性统计分析&#xff1a;均值、方差与分位数计算实战5.1.1 数据准备与分析目标数据集介绍分析目标 5.1.2 均值计算&#xff1a;从整体到分组分析总体均值计算加权均值…...

【PostgreSQL数据分析实战:从数据清洗到可视化全流程】5.4 数据抽样(简单随机抽样/分层抽样)

&#x1f449; 点击关注不迷路 &#x1f449; 点击关注不迷路 &#x1f449; 点击关注不迷路 文章大纲 PostgreSQL数据分析实战&#xff1a;数据抽样核心技术解析5.4 数据抽样&#xff1a;从简单随机到分层策略的深度实践5.4.1 简单随机抽样&#xff1a;概率均等的基础抽样方法…...

时间同步服务核心知识笔记:原理、配置

一、时间同步服务 在 Linux 系统中&#xff0c;准确的时间至关重要。对于服务器集群&#xff0c;时间同步确保各节点间数据处理和交互的一致性&#xff0c;避免因时间差异导致的事务处理错误、日志记录混乱等问题。在分布式系统中&#xff0c;时间同步有助于协调任务调度、数据…...

Leetcode刷题记录32——搜索二维矩阵 II

题源&#xff1a;https://leetcode.cn/problems/search-a-2d-matrix-ii/description/?envTypestudy-plan-v2&envIdtop-100-liked 题目描述&#xff1a; 思路一&#xff1a; &#x1f4a1; 解题思路&#xff1a;利用矩阵有序特性 双指针法&#xff08;Z 字形搜索&…...

【最新Python包管理工具UV的介绍和安装】

介绍 uv是一个非常快的 Python 包安装程序和 pip 解析器&#xff0c;用 Rust 编写&#xff0c;设计为pip-tools的直接替代品。 以下是官网给出的UV与其他包管理工具解决依赖&#xff08;左&#xff09;和安装包&#xff08;右&#xff09;的对比图。 可以看出UV是一个极快的 P…...

第二章-猜数游戏

猜数游戏 纸上得来终觉浅&#xff0c;绝知此事要躬行。实践才能出真知&#xff0c;因此本文内容将通过一个小项目快速帮我们上手Rust语言。其中可能会出现一些目前还不是很了解的知识&#xff0c;但没事&#xff0c;后续通过学习我们会慢慢了解的&#xff0c;现在我们先体会一…...

Go小技巧易错点100例(二十九)

随着 Go 语言的不断迭代&#xff0c;新版本带来了许多实用的标准库函数&#xff0c;使得代码更加简洁、可读性更强。本篇文章主要介绍 Go 1.21 版本中的一些新特性&#xff0c;涵盖 可变类型比较、slice 最大值与最小值、map 转换为 slice 以及 map 合并 等常见场景&#xff0c…...

游戏开发的TypeScript(5)TypeScript的类型转换

TypeScript的类型转换 游戏开发中&#xff0c;事件经常会携带一些数据&#xff0c;而这些数据会做类型上的转化&#xff0c;在 这种情况下&#xff0c;类型转换&#xff08;Type Assertion&#xff09;能够让你手动把某个值指定为特定类型。这在 TypeScript 无法自动推断出正确…...

旋转图像(中等)

借助辅助矩阵来翻转&#xff1a; 第i行第j列的元素会出现在新矩阵的第j行倒数第i列。 class Solution {public void rotate(int[][] matrix) {int n matrix.length;int[][] matrix_new new int[n][n];for (int i 0; i < n; i) {for (int j 0; j < n; j) {matrix_ne…...

慢sql处理流程和常见案例

思维导图: 在 MySQL 数据库管理中&#xff0c;慢查询是影响系统性能的常见痛点。随着 MySQL 8 版本的普及&#xff0c;其新增特性&#xff08;如 CTE、隐藏索引、JSON 格式执行计划等&#xff09;为慢查询优化提供了更强大的工具。本文结合 MySQL 8 的特性&#xff0c;通过代码…...

Kubernetes控制平面组件:Controller Manager 之 内置Controller详解

云原生学习路线导航页&#xff08;持续更新中&#xff09; kubernetes学习系列快捷链接 Kubernetes架构原则和对象设计&#xff08;一&#xff09;Kubernetes架构原则和对象设计&#xff08;二&#xff09;Kubernetes架构原则和对象设计&#xff08;三&#xff09;Kubernetes控…...

E-R图作业

1.一个图书馆借阅管理数据库要求提供下述服务&#xff1a; &#xff08;&#xff11;&#xff09;可随时查询书库中现有书籍的品种、数量与存放位置。所有各类书籍均可由书号惟一标识。 &#xff08;&#xff12;&#xff09;可随时查询书籍借还情况&#xff0c;包括借书人单位…...

debuginfo详解

debuginfo 是 Linux 系统中存储调试符号和源代码信息的特殊软件包&#xff0c;用于分析内核或用户态程序的崩溃转储文件&#xff08;如 vmcore、coredump&#xff09;。它在调试复杂问题&#xff08;如内核崩溃、程序段错误&#xff09;时至关重要。以下是其核心作用、安装方法…...

Android学习总结之GetX库篇(场景运用)

状态管理 在一个复杂的 Flutter 应用里&#xff0c;怎样借助 GetX 管理多个相互关联的状态&#xff0c;并且保证代码的可维护性和性能&#xff1f; 考察点&#xff1a;对 GetX 状态管理的深入理解&#xff0c;以及在复杂场景下运用它的能力。 解答思路&#xff1a; 采用模块…...

android-ndk开发(5): 编译运行 hello-world

android-ndk开发(5): 编译运行 hello-world 2025/05/05 1. 概要 hello-world 是每一门语言的第一个样例程序&#xff0c; 跑通它&#xff0c; 在一段时间内你会相当顺畅&#xff1a; 可以边学边实验&#xff0c; 根据运行结果得到反馈。 而对于 android-ndk 开发而言&#…...

【PostgreSQL数据分析实战:从数据清洗到可视化全流程】6.1 客户分群分析(RFM模型构建)

&#x1f449; 点击关注不迷路 &#x1f449; 点击关注不迷路 &#x1f449; 点击关注不迷路 文章大纲 PostgreSQL数据分析实战&#xff1a;RFM模型构建实现客户分群分析6.1 客户分群分析——RFM模型构建6.1.1 RFM模型核心指标解析6.1.2 数据准备与清洗规范数据表结构设计数据清…...

stm32之TIM定时中断详解

目录 1.引入1.1 简介1.2 类型1.2.1 基本定时器1.2.2 通用定时器1. 触发控制单元 (Trigger Control Unit)2. 输入捕获单元 (Input Capture Unit)3. 输出比较单元 (Output Compare Unit)4. CNT 计数器5. 自动重装载寄存器 (ARR)6. 预分频器 (PSC)7. 中断与 DMA 事件8. 刹车功能 (…...

【Hive入门】Hive安全管理与权限控制:用户认证与权限管理深度解析

目录 引言 1 Hive安全管理体系概述 2 Hive用户认证机制 2.1 Kerberos集成认证 2.1.1 Kerberos基本原理 2.1.2 Hive集成Kerberos配置步骤 2.1.3 Kerberos认证常见问题排查 2.2 LDAP用户同步 2.2.1 LDAP协议概述 2.2.2 Hive集成LDAP配置 2.2.3 LDAP与Hive用户同步架构…...

解决DNS劫持问题

什么是DNS劫持&#xff1f; DNS劫持&#xff08;DNS Hijacking&#xff09;是指通过篡改DNS配置&#xff0c;将用户的域名解析请求引导到恶意服务器的攻击方式。这种攻击常见于恶意软件、路由器漏洞或DNS配置被修改的情况下。攻击者通过这种方式控制了用户访问的网站&#xff…...

android-ndk开发(1): 搭建环境

android-ndk开发(1): 搭建环境 2025/05/05 1. 目的 写一些 C/C 代码&#xff0c; 例如 cv 基础算法&#xff0c; 并交叉编译到 android 平台。 不涉及 JNI、 Java、 Kotlin&#xff0c; 暂不涉及 rust。 基本上能适用于华为鸿蒙的 ohos ndk。 那么&#xff0c; 为了完成交叉…...

力扣面试150题-- 翻转二叉树

Day 41 题目描述 做法 /*** Definition for a binary tree node.* public class TreeNode {* int val;* TreeNode left;* TreeNode right;* TreeNode() {}* TreeNode(int val) { this.val val; }* TreeNode(int val, TreeNode left, TreeNode right…...

开源模型应用落地-qwen模型小试-Qwen3-8B-推理加速-vLLM(一)

一、前言 随着大语言模型的参数规模持续膨胀,如何在有限算力下实现高效推理成为行业焦点。阿里云推出的Qwen3-8B,凭借其卓越的语言理解与生成能力,已在多个基准测试中展现竞争力。而vLLM框架作为大模型部署的“加速器”,通过PagedAttention实现内存的高效管理,并支持连续批…...

brep2seq kaggle安装 micromamba conda环境

https://github.com/zhangshuming0668/Brep2Seq Micromamba Installation — documentation !curl -Ls https://micro.mamba.pm/api/micromamba/linux-64/latest | tar -xvj bin/micromamba A Synthetic CAD Models Dataset for Deep Learning kaggle只有20g&#xff0c;等我有…...

钩子函数和参数:Vue组件生命周期中的自定义逻辑

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》、《前端求职突破计划》 &#x1f35a; 蓝桥云课签约作者、…...

SpringBoot企业级开发之【文件上传】

看一下我们的需求&#xff1a; 接口文档&#xff1a; 分析思路&#xff1a; 现在我们先实现后端先&#xff1a; 实操&#xff1a; 一.存储到本地磁盘&#xff1a; 1.Controller 创建一个FileUploadController类 package org.huangyingyuan.controller;import org.huangyingyu…...

Linux系统安装PaddleDetection

一、安装cuda 1. 查看设备 先输入nvidia-smi&#xff0c;查看设备支持的最大cuda版本&#xff0c;选择官网中支持的cuda版本 https://www.paddlepaddle.org.cn/install/quick?docurl/documentation/docs/zh/install/conda/linux-conda.html 2. 下载CUDA并安装 使用快捷键…...

JVM 内存结构全解析

带你深入 JVM 内存结构,搞懂运行时数据区到底是怎么回事 JVM 的内存结构到底长什么样?程序计数器、虚拟机栈、堆、方法区、直接内存到底有什么用?这篇文章将从实际运行角度出发, 用一篇文章彻底讲透 JVM 的运行时数据区。一、为什么你必须搞懂 JVM 内存结构? 在一次线上…...

K8S node ARP 表爆满 如何优化

当 Kubernetes 节点的 ARP 表爆满时&#xff0c;可能会导致网络通信故障。以下是针对该问题的优化策略和解决方案&#xff1a; 一、ARP 表爆满的危害 网络不通&#xff1a;新的 ARP 请求无法被处理&#xff0c;导致数据包无法转发。性能下降&#xff1a;ARP 表查找效率降低&a…...

SpringMVC——第7章:HttpMessageConverter

一、HttpMessageConverter HttpMessageConverter是Spring MVC中非常重要的一个接口。翻译为&#xff1a;HTTP消息转换器。该接口下提供了很多实现类&#xff0c;不同的实现类有不同的转换方式。 1.什么是HTTP消息 HTTP消息其实就是HTTP协议。HTTP协议包括请求协议和响应协议。…...