数据结构——栈和队列
栈和队列的建立
- 前言
- 一、栈
- 1.栈的概念
- 2.栈的实现
- 3.代码示例
- (1)Stack.h
- (2)Stack.c
- (3)Test.c
- (4)运行结果
- (5)完整代码演示
- 二、队列
- 1.队列的概念
- 2.队列的实现
- 3.代码示例
- (1)Queue.h
- (2)Queue.c
- (3)Test.c
- (4)运行结果
- (5)完整代码演示
- 三、栈的应用例题
- 方法一
- 方法二
- 总结
前言
今天我们来学习栈和队列的简易建立!
在后面还会有一道栈的应用题,检测大家的用功程度!
加油吧!
一、栈
1.栈的概念
栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。 进行数据插入和删除操作的一端称为栈顶,另一端称为栈底。
栈中的数据元素遵守后进先出LIFO(Last In First Out)的原则。 压栈:栈的插入操作叫做进栈/压栈/入栈,入数据在栈顶。
出栈:栈的删除操作叫做出栈。出数据也在栈顶。
模型图示例:
2.栈的实现
栈的实现一般可以使用数组或者链表实现,相对而言数组的结构实现更优一些。因为数组在尾上插入数据的代价比较小。
图片示例:
3.代码示例
(1)Stack.h
1.头文件的声明
//头文件的声明
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>
2.栈的接口定义
//栈的接口定义
typedef int STDataType;
typedef struct Stack
{STDataType* a;int top;int capacity;
}ST;
3.初始化和销毁函数的声明
//初始化
void STInit(ST* ps);
//销毁
void STDestroy(ST* ps);
4.入栈和出栈函数的声明
//插入
void STPush(ST* ps, STDataType x);
//删除
void STPop(ST* ps);
5.查找栈顶元素和长度计算函数以及判空函数的声明
//插入
//查找栈顶元素
STDataType STTop(ST* ps);
//长度计算
int STSize(ST* ps);
//判断是否为空
bool STEmpty(ST* ps);
(2)Stack.c
1.头文件的声明
#include "Stack.h"
2.初始化和销毁函数的定义
/初始化
void STInit(ST* ps)
{assert(ps);ps->a = NULL;ps->capacity = 0;ps->top = 0;
}//销毁
void STDestroy(ST* ps)
{assert(ps);free(ps->a);ps->a = NULL;ps->top = ps->capacity = 0;
}
3.入栈和出栈函数的定义
//插入
void STPush(ST* ps, STDataType x)
{assert(ps);if (ps->top == ps->capacity){int newCapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;STDataType* tmp = (STDataType*)realloc(ps->a, sizeof(STDataType) * newCapacity);if (tmp == NULL){perror("realloc fail");exit(-1);}ps->a = tmp;ps->capacity = newCapacity;}ps->a[ps->top] = x;ps->top++;
}//删除栈顶元素
void STPop(ST* ps)
{assert(ps);assert(ps->top > 0);--ps->top;
}
4.查找栈顶元素和长度计算函数以及判空函数的定义
//查找栈顶元素
STDataType STTop(ST* ps)
{assert(ps);assert(ps->top > 0);return ps->a[ps->top - 1];
}//长度计算
int STSize(ST* ps)
{assert(ps);return ps->top;
}//判断是否为空
bool STEmpty(ST* ps)
{assert(ps);return ps->top == 0;
}
(3)Test.c
1.头文件的声明
#include "Stack.h"
2.测试函数的定义
void TestStack()
{ST st;STInit(&st);STPush(&st, 1);STPush(&st, 2);STPush(&st, 3);STPush(&st, 4);STPush(&st, 5);while (!STEmpty(&st)){printf("%d ", STTop(&st));STPop(&st);}printf("\n");STPush(&st, 6);STPush(&st, 7);STPush(&st, 8);STPush(&st, 9);STPush(&st, 10);while (!STEmpty(&st)){printf("%d ", STTop(&st));STPop(&st);}printf("\n");STDestroy(&st);
}
3.主函数的定义
int main()
{TestStack();return 0;
}
(4)运行结果
(5)完整代码演示
1.Stack.h
#pragma once
//头文件的声明
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>//栈的接口定义
typedef int STDataType;
typedef struct Stack
{STDataType* a;int top;int capacity;
}ST;//初始化
void STInit(ST* ps);
//销毁
void STDestroy(ST* ps);
//插入
void STPush(ST* ps, STDataType x);
//删除
void STPop(ST* ps);
//查找栈顶元素
STDataType STTop(ST* ps);
//长度计算
int STSize(ST* ps);
//判断是否为空
bool STEmpty(ST* ps);
2.Stack.c
#include "Stack.h"//初始化
void STInit(ST* ps)
{assert(ps);ps->a = NULL;ps->capacity = 0;ps->top = 0;
}//销毁
void STDestroy(ST* ps)
{assert(ps);free(ps->a);ps->a = NULL;ps->top = ps->capacity = 0;
}//插入
void STPush(ST* ps, STDataType x)
{assert(ps);if (ps->top == ps->capacity){int newCapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;STDataType* tmp = (STDataType*)realloc(ps->a, sizeof(STDataType) * newCapacity);if (tmp == NULL){perror("realloc fail");exit(-1);}ps->a = tmp;ps->capacity = newCapacity;}ps->a[ps->top] = x;ps->top++;
}//删除栈顶元素
void STPop(ST* ps)
{assert(ps);assert(ps->top > 0);--ps->top;
}//查找栈顶元素
STDataType STTop(ST* ps)
{assert(ps);assert(ps->top > 0);return ps->a[ps->top - 1];
}//长度计算
int STSize(ST* ps)
{assert(ps);return ps->top;
}//判断是否为空
bool STEmpty(ST* ps)
{assert(ps);return ps->top == 0;
}
3.Test.c
#include "Stack.h"void TestStack1()
{ST st;STInit(&st);STPush(&st, 1);STPush(&st, 2);STPush(&st, 3);STPush(&st, 4);STPush(&st, 5);while (!STEmpty(&st)){printf("%d ", STTop(&st));STPop(&st);}printf("\n");STPush(&st, 6);STPush(&st, 7);STPush(&st, 8);STPush(&st, 9);STPush(&st, 10);while (!STEmpty(&st)){printf("%d ", STTop(&st));STPop(&st);}printf("\n");STDestroy(&st);
}int main()
{TestStack1();return 0;
}
二、队列
1.队列的概念
队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出 FIFO(First In First Out)
入队列:进行插入操作的一端称为队尾 出队列:进行删除操作的一端称为队头
模型图示例:
2.队列的实现
队列也可以数组和链表的结构实现,使用链表的结构实现更优一些,因为如果使用数组的结构,出队列在数组头上出数据,效率会比较低。
图片示例:
3.代码示例
(1)Queue.h
1.头文件的声明
#pragma once
//头文件的声明
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>
2.队列接口的定义
//链表接口定义
typedef int QDataType;
typedef struct QueueNode
{struct QueueNode* next;QDataType data;
}QNode;//队列接口定义
typedef struct Queue
{QNode* head;QNode* tail;int size;
}Que;
3.初始化和销毁函数的声明
//队列初始化
void QueueInit(Que* pq);
//队列销毁
void QueueDestroy(Que* pq);
4.入队列和出队列函数的声明
//插入
void QueuePush(Que* pq, QDataType x);
//删除
void QueuePop(Que* pq);
5.查找队头、查找队尾函数的声明
//查找队头元素
QDataType QueueFront(Que* pq);
//查找队尾元素
QDataType QueueBack(Que* pq);
6.判空以及长度计算函数的声明
//判断是否为空
bool QueueEmpty(Que* pq);
//计算长度
int QueueSize(Que* pq);
(2)Queue.c
1.头文件的声明
#include "Queue.h"
2.初始化和销毁函数的定义
void QueueInit(Que* pq)
{assert(pq);pq->head = pq->tail = NULL;pq->size = 0;
}void QueueDestroy(Que* pq)
{assert(pq);QNode* cur = pq->head;while (cur){QNode* next = cur->next;free(cur);cur = next;}pq->head = pq->tail = NULL;pq->size = 0;
}
3.入队列和出队列函数的定义
void QueuePush(Que* pq, QDataType x)
{assert(pq);QNode* newnode = (QNode*)malloc(sizeof(QNode));if (newnode == NULL){perror("malloc fail");exit(-1);}newnode->data = x;newnode->next = NULL;if (pq->tail == NULL){pq->head = pq->tail = newnode;}else{pq->tail->next = newnode;pq->tail = newnode;}pq->size++;
}void QueuePop(Que* pq)
{assert(pq);//判断队列指针指向是否为空assert(!QueueEmpty(pq));//判断队列里面的数据是否为空if (pq->head->next == NULL){free(pq->head);pq->head = pq->tail = NULL;}else{QNode* next = pq->head->next;free(pq->head);pq->head = next;}pq->size--;
}
4.查找队头、查找队尾函数的定义
//查找队头元素
QDataType QueueFront(Que* pq)
{assert(pq);assert(!QueueEmpty(pq));return pq->head->data;
}//查找队尾元素
QDataType QueueBack(Que* pq)
{assert(pq);assert(!QueueEmpty(pq));return pq->tail->data;
}
5.判空以及长度计算函数的定义
//判断是否为空
bool QueueEmpty(Que* pq)
{assert(pq);return pq->head == NULL;
}//长度计算
int QueueSize(Que* pq)
{assert(pq);return pq->size;
}
(3)Test.c
1.头文件的声明
#include "Queue.h"
2.测试函数的定义
void QueueTest() {Que pq;QueueInit(&pq);QueuePush(&pq, 1);QueuePush(&pq, 2);QueuePush(&pq, 3);QueuePush(&pq, 4);QueuePush(&pq, 5);while (!QueueEmpty(&pq)) {printf("%d ", QueueFront(&pq));QueuePop(&pq);}QueueDestroy(&pq);
}
3.主函数的定义
int main() {QueueTest();return 0;
}
(4)运行结果
(5)完整代码演示
1.Queue.h
#pragma once
//头文件的声明
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>//链表接口定义
typedef int QDataType;
typedef struct QueueNode
{struct QueueNode* next;QDataType data;
}QNode;//队列接口定义
typedef struct Queue
{QNode* head;QNode* tail;int size;
}Que;//队列初始化
void QueueInit(Que* pq);
//队列销毁
void QueueDestroy(Que* pq);
//插入
void QueuePush(Que* pq, QDataType x);
//删除
void QueuePop(Que* pq);
//查找队头元素
QDataType QueueFront(Que* pq);
//查找队尾元素
QDataType QueueBack(Que* pq);
//判断是否为空
bool QueueEmpty(Que* pq);
//计算长度
int QueueSize(Que* pq);
2.Queue.c
#include "Queue.h"void QueueInit(Que* pq)
{assert(pq);pq->head = pq->tail = NULL;pq->size = 0;
}void QueueDestroy(Que* pq)
{assert(pq);QNode* cur = pq->head;while (cur){QNode* next = cur->next;free(cur);cur = next;}pq->head = pq->tail = NULL;pq->size = 0;
}void QueuePush(Que* pq, QDataType x)
{assert(pq);QNode* newnode = (QNode*)malloc(sizeof(QNode));if (newnode == NULL){perror("malloc fail");exit(-1);}newnode->data = x;newnode->next = NULL;if (pq->tail == NULL){pq->head = pq->tail = newnode;}else{pq->tail->next = newnode;pq->tail = newnode;}pq->size++;
}void QueuePop(Que* pq)
{assert(pq);//判断队列指针指向是否为空assert(!QueueEmpty(pq));//判断队列里面的数据是否为空if (pq->head->next == NULL){free(pq->head);pq->head = pq->tail = NULL;}else{QNode* next = pq->head->next;free(pq->head);pq->head = next;}pq->size--;
}//查找队头元素
QDataType QueueFront(Que* pq)
{assert(pq);assert(!QueueEmpty(pq));return pq->head->data;
}//查找队尾元素
QDataType QueueBack(Que* pq)
{assert(pq);assert(!QueueEmpty(pq));return pq->tail->data;
}//判断是否为空
bool QueueEmpty(Que* pq)
{assert(pq);return pq->head == NULL;
}//长度计算
int QueueSize(Que* pq)
{assert(pq);return pq->size;
}
3.Test.c
#include "Queue.h"void QueueTest() {Que pq;QueueInit(&pq);QueuePush(&pq, 1);QueuePush(&pq, 2);QueuePush(&pq, 3);QueuePush(&pq, 4);QueuePush(&pq, 5);while (!QueueEmpty(&pq)) {printf("%d ", QueueFront(&pq));QueuePop(&pq);}QueueDestroy(&pq);
}int main() {QueueTest();return 0;
}
三、栈的应用例题
题目:括号匹配问题
题目链接
提示:
. 1 <= s.length <= 104
. s 仅由括号 ‘()[]{}’ 组成
解题思路:
这道题我有两种解法!
建栈法和暴力破解法!
方法一
首先第一种就是利用栈来解决:
1.左括号,入栈;
2.右括号与栈中的栈顶括号进行匹配;
图例:
代码示例:
引用之前栈的建立函数:
//栈的接口定义
typedef int STDataType;
typedef struct Stack
{STDataType* a;int top;int capacity;
}ST;//初始化
void STInit(ST* ps);
//销毁
void STDestroy(ST* ps);
//插入
void STPush(ST* ps, STDataType x);
//删除
void STPop(ST* ps);
//查找栈顶元素
STDataType STTop(ST* ps);
//长度计算
int STSize(ST* ps);
//判断是否为空
bool STEmpty(ST* ps);//初始化
void STInit(ST* ps)
{assert(ps);ps->a = NULL;ps->capacity = 0;ps->top = 0;
}//销毁
void STDestroy(ST* ps)
{assert(ps);free(ps->a);ps->a = NULL;ps->top = ps->capacity = 0;
}//插入
void STPush(ST* ps, STDataType x)
{assert(ps);if (ps->top == ps->capacity){int newCapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;STDataType* tmp = (STDataType*)realloc(ps->a, sizeof(STDataType) * newCapacity);if (tmp == NULL){perror("realloc fail");exit(-1);}ps->a = tmp;ps->capacity = newCapacity;}ps->a[ps->top] = x;ps->top++;
}//删除栈顶元素
void STPop(ST* ps)
{assert(ps);assert(ps->top > 0);--ps->top;
}//查找栈顶元素
STDataType STTop(ST* ps)
{assert(ps);assert(ps->top > 0);return ps->a[ps->top - 1];
}//长度计算
int STSize(ST* ps)
{assert(ps);return ps->top;
}//判断是否为空
bool STEmpty(ST* ps)
{assert(ps);return ps->top == 0;
}
功能函数的定义
bool isValid(char* s) {ST st;STInit(&st);char topVal;while (*s ) {if (*s == '(' || *s == '[' || *s == '{') {STPush(&st, *s);}else {//数量不匹配if (STEmpty(&st)){STDestroy(&st);return false;}topVal = STTop(&st);STPop(&st);if ((*s == ']' && topVal != '[')|| (*s == ']' && topVal != '[')|| (*s == ']' && topVal != '[')) {STDestroy(&st);return false;}}++s;}bool ret = STEmpty(&st);STDestroy(&st);return ret;
}
方法二
第二种方法就是例子中如果不存在无效括号的话,那么至少有一个是左右括号相邻的;
所以先找到相邻且匹配的括号将其移除,然后慢慢一点一点全部都移除的话则说明全部括号有效!
图例
代码演示:
bool isValid(char* s) {char* p = s;while (*p) {p = s;while (*p) {if (*p + 1 == *(p + 1) || *p + 2 == *(p + 1)) {//查看assii码表了解符号的大小char* move = p;while (true) {*move = *(move + 2);if(*move=='\0')break;move++;}break;}else {p++;}}if (*p == '\0' && *s != '\0')return false;}return true;
}
总结
今天的内容有点多,希望大家仔细观看,细细揣摩!
好好学习,天天向上!
不变的真理!
相关文章:

数据结构——栈和队列
栈和队列的建立 前言一、栈1.栈的概念2.栈的实现3.代码示例(1)Stack.h(2)Stack.c(3)Test.c(4)运行结果(5)完整代码演示 二、队列1.队列的概念2.队列的实现3.代…...
苍穹外卖阿里云oss存储笔记
阿里云oss 阿里云对象存储oss(Object Storage Service),是一款海量,安全,低成本,高可靠得云存储服务,使用oss,您可以通过网络随时存储和调用包括文本,图片,视…...

Kafka 集群搭建过程
前言 跟着尚硅谷海哥文档搭建的Kafka集群环境,在此记录一下,侵删 注意:博主在服务器上搭建环境的时候使用的是一个服务器,所以这篇博客可能会出现一些xsync分发到其他服务器时候的错误,如果你在搭建的过程中出现了错…...

【算法随记】在计算过程中模的情况
https://leetcode.cn/problems/power-of-heroes/ 计算过程中,可以放心模的情况: 加减乘 先模再加再模和直接加再模一样 a m o d m b m o d m ≡ a b ( m o d m ) a\mod mb\mod m ≡ ab \ (\mod m) amodmbmodm≡ab (modm) 先模再减再模和直接减再模…...

MSTP多生成树协议(第二课)
MSTP负载均衡 实验 需求 1)PC1属于 vlan 10 ,IP地址为 192.168.10.1/24, 网关为 192.168.10.2542)PC2属于 vlan 20 ,IP地址为 192.168.20.1/24, 网关为 192.168.20.254**3)确保PC1与PC2互通4…...
数组指针、函数指针、指针数组、函数 指针数组、指针函数详细总结
1.数组指针概念和应用 首先数组指针应该是一个数组,它的定义如下: 数组指针,指的是数组名的指针,即数组首元素地址的指针。即是指向数组的指针。例:int (*p)[10]; p即为指向数组的指针,又称数组指针。 数…...

Linux存储学习笔记
相关文章 Linux 存储系列|请描述一下文件的 io 栈? - tcpisopen的文章 - 知乎 https://zhuanlan.zhihu.com/p/478443978 深入学习 Linux 操作系统的存储 IO 堆栈 - KaiwuDB的文章 - 知乎 https://zhuanlan.zhihu.com/p/636720297 linux存储栈概览 - st…...

ubuntu执行jmeter端口不够用报错(Address not available)
ubuntu执行jmeter端口不够用报错(Address not available) 解决方案 // 增加本地端口范围 echo 1024 65000 > /proc/sys/net/ipv4/ip_local_port_range// 启用快速回收TIME_WAIT套接字 sudo sysctl -w net.ipv4.tcp_tw_recycle 1// 启用套接字的重用 sudo sysctl -w net.ipv4…...
MongoDB:简单的增删改查操作
一.概述 本篇文章介绍在Navicat中对MongoDB数据库进行增删改查操作,在后面会介绍在Spring Boot中使用MongoTemplate对MongoDB数据库进行相关操作.如有必要可以先看看前面几篇文章. MongoDB:MySQL,Redis,ES,MongoDB的应用场景 MongoDB:数据库初步应用 二.在Navicat进行增删改…...
网络编程(域套接字)
一、域套接字的概念 1.只能做一台主机内的进程间通信,协议族(地址族)指定为:AF_UNIX AF_LOCAL 2.bsp-lcd: s类型文件,就是域套接字 3.如果客户端不手动绑定,则操作系统不会创建一个套接字文件…...
探索短视频小程序/小年糕
短视频小程序的兴起,为创作者提供了一个全新的平台,让他们能够以更专业的方式展现自己的作品。这种创作形式不仅要求作品内容足够精彩还需要有深度的思考和逻辑性的呈现。本文将探索短视频小程序的专业与深度的创作之道,帮助创作者更好地发挥…...

基于MATLAB开发AUTOSAR软件应用层Code mapping专题-part 7 Function callers标签页介绍
不知不觉这个code-mapping专题已经写了6篇文章了,今天是我们这个专题的最后一篇文章了介绍Function callers 这个其实很简单,以前的文章里也有提到CS接口实现两个SWC之间的CS调用,我们在从Code-mapping的角度在说下 首先还是看下模型 我们还记得在simulink里我们用function…...

ARM开发(cortex-A7核中断实验)
1.实验目的:实现KEY1/LEY2/KE3三个按键,中断触发打印一句话,并且灯的状态取反; key1 ----> LED3灯状态取反; key2 ----> LED2灯状态取反; key3 ----> LED1灯状态取反; 2.分析框图: …...

关于融合项目点云pointpillars检测不显示三维检测框问题的解决
这个问题主要还是launch文件中出现了一些偏差。 launch文件的第26行 这里原先是0.6,在检测kitti的时候是0.6,由于kitti是64线激光雷达,我个人用的是16线激光雷达,所以把0.6降到了0.2.出现了三维检测框,问题解决...

spring复习:(57)PropertyOverrideConfigurer用法及工作原理
一、属性配置文件 dataSource.urljdbc:mysql://xxx.xxx.xxx.xxx/test dataSource.usernameroot dataSource.passwordxxxxxx dataSource.driverClassNamecom.mysql.jdbc.Driver #dataSource.typecom.alibaba.druid.pool.DruidDataSource二、spring配置文件 <?xml version&…...
在axios中获取文件上传进度
1.在axios 全局配置的文件中加入一个postFile 方法在上传文件时调用。 export function postFile(url, params,config) {return new Promise((resolve, reject) > {axios.post(url, params,config).then(res > {resolve(res);}).catch(err > {reject(err);})}) } 2.…...
黑马头条-kafka配置
生产者配置 NAMEDESCRIPTIONTYPEDEFAULTVALID VALUESIMPORTANCEbootstrap.servershost/port列表,用于初始化建立和Kafka集群的连接。列表格式为host1:port1,host2:port2,…,无需添加所有的集群地址,kafka会根据提供的地址发现其他的地址&…...

PMP P-01 Basic Knowledge
PMP基础知识...

java八股文面试[数据结构]——ArrayList和LinkedList区别
ArrayList和LinkedList的异同 二者的线程都不安全,相对线程安全的Vector,执行效率高。此外,ArrayList时实现了基于动态数组的数据结构,LinkedList基于链表的数据结构,对于随机访问get和set,ArrayList觉得优于LinkedLis…...

OpenCV中QR二维码的生成与识别(CIS摄像头解析)
1、QR概述 QR(Quick Response)属于二维条码的一种,意思是快速响应的意思。QR码不仅信息容量大、可靠性高、成本低,还可表示汉字及图像等多种文字信息、其保密防伪性强而且使用非常方便。更重要的是QR码这项技术是开源的,在移动支付、电影票、…...

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)
题目:3442. 奇偶频次间的最大差值 I 思路 :哈希,时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况,哈希表这里用数组即可实现。 C版本: class Solution { public:int maxDifference(string s) {int a[26]…...
SkyWalking 10.2.0 SWCK 配置过程
SkyWalking 10.2.0 & SWCK 配置过程 skywalking oap-server & ui 使用Docker安装在K8S集群以外,K8S集群中的微服务使用initContainer按命名空间将skywalking-java-agent注入到业务容器中。 SWCK有整套的解决方案,全安装在K8S群集中。 具体可参…...
【杂谈】-递归进化:人工智能的自我改进与监管挑战
递归进化:人工智能的自我改进与监管挑战 文章目录 递归进化:人工智能的自我改进与监管挑战1、自我改进型人工智能的崛起2、人工智能如何挑战人类监管?3、确保人工智能受控的策略4、人类在人工智能发展中的角色5、平衡自主性与控制力6、总结与…...

基于FPGA的PID算法学习———实现PID比例控制算法
基于FPGA的PID算法学习 前言一、PID算法分析二、PID仿真分析1. PID代码2.PI代码3.P代码4.顶层5.测试文件6.仿真波形 总结 前言 学习内容:参考网站: PID算法控制 PID即:Proportional(比例)、Integral(积分&…...

理解 MCP 工作流:使用 Ollama 和 LangChain 构建本地 MCP 客户端
🌟 什么是 MCP? 模型控制协议 (MCP) 是一种创新的协议,旨在无缝连接 AI 模型与应用程序。 MCP 是一个开源协议,它标准化了我们的 LLM 应用程序连接所需工具和数据源并与之协作的方式。 可以把它想象成你的 AI 模型 和想要使用它…...
基础测试工具使用经验
背景 vtune,perf, nsight system等基础测试工具,都是用过的,但是没有记录,都逐渐忘了。所以写这篇博客总结记录一下,只要以后发现新的用法,就记得来编辑补充一下 perf 比较基础的用法: 先改这…...
css3笔记 (1) 自用
outline: none 用于移除元素获得焦点时默认的轮廓线 broder:0 用于移除边框 font-size:0 用于设置字体不显示 list-style: none 消除<li> 标签默认样式 margin: xx auto 版心居中 width:100% 通栏 vertical-align 作用于行内元素 / 表格单元格ÿ…...
Device Mapper 机制
Device Mapper 机制详解 Device Mapper(简称 DM)是 Linux 内核中的一套通用块设备映射框架,为 LVM、加密磁盘、RAID 等提供底层支持。本文将详细介绍 Device Mapper 的原理、实现、内核配置、常用工具、操作测试流程,并配以详细的…...

算法岗面试经验分享-大模型篇
文章目录 A 基础语言模型A.1 TransformerA.2 Bert B 大语言模型结构B.1 GPTB.2 LLamaB.3 ChatGLMB.4 Qwen C 大语言模型微调C.1 Fine-tuningC.2 Adapter-tuningC.3 Prefix-tuningC.4 P-tuningC.5 LoRA A 基础语言模型 A.1 Transformer (1)资源 论文&a…...
Java + Spring Boot + Mybatis 实现批量插入
在 Java 中使用 Spring Boot 和 MyBatis 实现批量插入可以通过以下步骤完成。这里提供两种常用方法:使用 MyBatis 的 <foreach> 标签和批处理模式(ExecutorType.BATCH)。 方法一:使用 XML 的 <foreach> 标签ÿ…...