C语言实现数据结构之队列
目录
- 队列
- 一. 队列的概念及结构
- 二. 队列的实现
- 1. 要实现的功能
- 2 具体的实现
- 2.1 结构体
- 2.2 初始化
- 2.3 入队列
- 2.4 出队列
- 2.5 返回队首元素
- 2.6 返回队尾元素
- 2.7 队列元素个数
- 2.8 队列判空
- 2.9 队列销毁
- 三. 队列相关OJ题
- 设计循环队列
- 用队列实现栈
- 用栈实现队列
- 四. 概念选择题
- 五. 参考代码
- Queue.h
- Queue.c
- test.c
队列
一. 队列的概念及结构
队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出FIFO(First In First Out)
入队列:进行插入操作的一端称为队尾
出队列:进行删除操作的一端称为队头
二. 队列的实现
队列也可以数组和链表的结构实现,使用链表的结构实现更优一些,因为如果使用数组的结构,出队列在数组头上出数据,效率会比较低。
1. 要实现的功能
// 链式结构:表示队列
typedef struct QListNode
{
struct QListNode* _pNext;
QDataType _data;
}QNode;
// 队列的结构
typedef struct Queue
{
QNode* _front;
QNode* _rear;
}Queue;
// 初始化队列
void QueueInit(Queue* q);
// 队尾入队列
void QueuePush(Queue* q, QDataType data);
// 队头出队列
void QueuePop(Queue* q);
// 获取队列头部元素
QDataType QueueFront(Queue* q);
// 获取队列队尾元素
QDataType QueueBack(Queue* q);
// 获取队列中有效元素个数
int QueueSize(Queue* q);
// 检测队列是否为空,如果为空返回非零结果,如果非空返回0
int QueueEmpty(Queue* q);
// 销毁队列
void QueueDestroy(Queue* q);
另外扩展了解一下,实际中我们有时还会使用一种队列叫循环队列。如操作系统课程讲解生产者消费者模型时可以就会使用循环队列。环形队列可以使用数组实现,也可以使用循环链表实现。
2 具体的实现
本次队列的实现我们基于双向链表。
2.1 结构体
为了适配多种数据类型,这里使用typedef对数据类型进行重命名,便于进行统一修改。
由于链表QueueNode的节点只含有next指针和值,所以我们额外定义一个结构体Queue记录下链表的头和尾,便于快速进行相关操作。
typedef int QDataType;typedef struct QueueNode
{struct QueueNode* next;QDataType val;
}QNode;typedef struct Queue
{QNode* phead; QNode* ptail;int size;
}Queue;
2.2 初始化
初始化将记录的头和尾置空,元素个数置空
void QueueInit(Queue* pq)
{assert(pq);pq->phead = NULL;pq->ptail = NULL;pq->size = 0;
}
2.3 入队列
入队列创建一个新节点,并放在记录好的尾节点的位置之后,成为新的尾节点,最后元素个数增加。
void QueuePush(Queue* pq, QDataType x)
{QNode* newnode = (QNode*)malloc(sizeof(QNode));if (newnode == NULL){perror("malloc failed");exit(1);}newnode->next = NULL;newnode->val = x;if (pq->ptail == NULL){pq->phead = newnode;pq->ptail = newnode;}else{pq->ptail->next = newnode;pq->ptail = newnode;}pq->size++;
}
2.4 出队列
出队列释放掉第一个节点(头节点),然后让第二个节点成为新的头节点,最后元素个数减少。
void QueuePop(Queue* pq)
{assert(pq);assert(pq->size);QNode* next = pq->phead->next;free(pq->phead);pq->phead = next;if (pq->phead == NULL)//just one node{pq->ptail = NULL;}pq->size--;
}
2.5 返回队首元素
返回我们记录的头节点的值即可。
QDataType QueueFront(Queue* pq)
{assert(pq);assert(pq->phead);return pq->phead->val;
}
2.6 返回队尾元素
返回我们记录的尾节点的值即可。
QDataType QueueBack(Queue* pq)
{assert(pq);assert(pq->ptail);return pq->ptail->val;
}
2.7 队列元素个数
返回我们记录的元素个数即可。
int QueueSize(Queue* pq)
{assert(pq);return pq->size;
}
2.8 队列判空
返回我们记录的元素个数是否为零。
_Bool QueueEmpty(Queue* pq)
{assert(pq);return pq->size == 0;
}
2.9 队列销毁
类似于单链表的销毁,依次销毁每一个节点后将头尾置空,将元素个数置空。
void QueueDestroy(Queue* pq)
{assert(pq);QNode* pcur = pq->phead;while (pcur){QNode* next = pcur->next;free(pcur);pcur = next;}pq->phead = NULL;pq->ptail = NULL;pq->size = 0;
}
三. 队列相关OJ题
设计循环队列
题目链接:设计循环队列
//顺序表
typedef struct
{int* a;int head;int tail;int k;
} MyCircularQueue;bool myCircularQueueIsEmpty(MyCircularQueue* obj);
bool myCircularQueueIsFull(MyCircularQueue* obj);MyCircularQueue* myCircularQueueCreate(int k)
{MyCircularQueue* pq = (MyCircularQueue*)malloc(sizeof(MyCircularQueue));//多开辟一个空间解决假溢出问题pq->a = malloc(sizeof(int) * (k + 1));pq->head = 0;pq->tail = 0;pq->k = k;return pq;
}bool myCircularQueueEnQueue(MyCircularQueue* obj, int value)
{if(myCircularQueueIsFull(obj)){return false;}obj->a[obj->tail] = value;obj->tail++;obj->tail %= (obj->k + 1);return true;
}bool myCircularQueueDeQueue(MyCircularQueue* obj)
{if(myCircularQueueIsEmpty(obj)){return false;} obj->head++;obj->head %= obj->k + 1;return true;
}int myCircularQueueFront(MyCircularQueue* obj)
{if(myCircularQueueIsEmpty(obj)){return EOF;}else{return obj->a[obj->head];}
}int myCircularQueueRear(MyCircularQueue* obj)
{if(myCircularQueueIsEmpty(obj)){return EOF;}else{//return obj->tail == 0 ? obj->a[obj->k] : obj->a[obj->tail - 1];//return obj->a[(obj->tail - 1 + obj->k + 1) % (obj->k + 1)];return obj->a[(obj->tail + obj->k) % (obj->k + 1)];}
}bool myCircularQueueIsEmpty(MyCircularQueue* obj)
{return obj->head == obj->tail;
}bool myCircularQueueIsFull(MyCircularQueue* obj)
{return (obj->tail + 1) % (obj->k + 1) == obj->head;
}void myCircularQueueFree(MyCircularQueue* obj)
{free(obj->a);free(obj);
}/*** Your MyCircularQueue struct will be instantiated and called as such:* MyCircularQueue* obj = myCircularQueueCreate(k);* bool param_1 = myCircularQueueEnQueue(obj, value);* bool param_2 = myCircularQueueDeQueue(obj);* int param_3 = myCircularQueueFront(obj);* int param_4 = myCircularQueueRear(obj);* bool param_5 = myCircularQueueIsEmpty(obj);* bool param_6 = myCircularQueueIsFull(obj);* myCircularQueueFree(obj);
*/
用队列实现栈
题目链接:用队列实现栈
typedef int QDataType;typedef struct QueueNode
{struct QueueNode* next;QDataType val;
}QNode;typedef struct Queue
{QNode* phead; QNode* ptail;int size;
}Queue;队尾插入
//void QueuePush(QNode** pphead, QNode** pptail, QDataType x);
//
队头删除
//void QueuePop(QNode** pphead, QNode** pptail);//初始化
void QueueInit(Queue* pq);//队尾插入
void QueuePush(Queue* pq, QDataType x);//队头删除
void QueuePop(Queue* pq);//取队头数据
QDataType QueueFront(Queue* pq);//取队尾数据
QDataType QueueBack(Queue* pq);//队列元素个数
int QueueSize(Queue* pq);//判空
_Bool QueueEmpty(Queue* pq);//队列的销毁
void QueueDestroy(Queue* pq);void QueueInit(Queue* pq)
{assert(pq);pq->phead = NULL;pq->ptail = NULL;pq->size = 0;
}void QueuePush(Queue* pq, QDataType x)
{QNode* newnode = (QNode*)malloc(sizeof(QNode));if (newnode == NULL){perror("malloc failed");exit(1);}newnode->next = NULL;newnode->val = x;if (pq->ptail == NULL){pq->phead = newnode;pq->ptail = newnode;}else{pq->ptail->next = newnode;pq->ptail = newnode;}pq->size++;
}void QueuePop(Queue* pq)
{assert(pq);assert(pq->size);QNode* next = pq->phead->next;free(pq->phead);pq->phead = next;if (pq->phead == NULL){pq->ptail = NULL;}pq->size--;
}QDataType QueueFront(Queue* pq)
{assert(pq);assert(pq->phead);return pq->phead->val;
}QDataType QueueBack(Queue* pq)
{assert(pq);assert(pq->ptail);return pq->ptail->val;
}int QueueSize(Queue* pq)
{assert(pq);return pq->size;
}_Bool QueueEmpty(Queue* pq)
{assert(pq);return pq->size == 0;
}void QueueDestroy(Queue* pq)
{assert(pq);QNode* pcur = pq->phead;while (pcur){QNode* next = pcur->next;free(pcur);pcur = next;}pq->phead = NULL;pq->ptail = NULL;pq->size = 0;
}typedef struct {Queue q1;Queue q2;
} MyStack;MyStack* myStackCreate()
{MyStack* pst = (MyStack*)malloc(sizeof(MyStack));if(pst == NULL){perror("malloc failed");exit(1);}QueueInit(&pst->q1);QueueInit(&pst->q2);return pst;
}void myStackPush(MyStack* obj, int x)
{if(!QueueEmpty(&(obj->q1))){QueuePush(&(obj->q1), x);}else{QueuePush(&(obj->q2), x);}
}int myStackPop(MyStack* obj)
{//如果队列不为空,就把前size - 1个数据放在另一个队列中,释放最后一个节点的数据Queue* emp = &(obj->q1);//假设q1为空Queue* noemp = &(obj->q2);if(QueueEmpty(&(obj->q2)))//如果q2为空{emp = &(obj->q2);noemp = &(obj->q1);}int sz = QueueSize(noemp);while(sz > 1){QueuePush(emp, QueueFront(noemp));QueuePop(noemp);sz--;}int top = QueueFront(noemp);QueuePop(noemp);return top;
}int myStackTop(MyStack* obj)
{if(!QueueEmpty(&(obj->q1))){return QueueBack(&(obj->q1));}else{return QueueBack(&(obj->q2));}
}bool myStackEmpty(MyStack* obj)
{return QueueEmpty(&(obj->q1)) && QueueEmpty(&(obj->q2));
}void myStackFree(MyStack* obj)
{QueueDestroy(&obj->q1);QueueDestroy(&obj->q2);free(obj);
}/*** Your MyStack struct will be instantiated and called as such:* MyStack* obj = myStackCreate();* myStackPush(obj, x);* int param_2 = myStackPop(obj);* int param_3 = myStackTop(obj);* bool param_4 = myStackEmpty(obj);* myStackFree(obj);
*/
用栈实现队列
题目链接:用栈实现队列
typedef int STDataType;typedef struct Stack
{STDataType* a;int top;int capacity;
}ST;//初始化
void STInit(ST* pst);//销毁
void STDestroy(ST* pst);//插入数据(入栈)
void STPush(ST* pst, STDataType x);//删除数据(出栈)
void STPop(ST* pst);//获取栈顶数据
STDataType STTop(ST* pst);//判空
_Bool STEmpty(ST* pst);//获取数据个数
int STSize(ST* pst);void STInit(ST* pst)
{assert(pst);pst->a = NULL;pst->capacity = 0;// top指向栈顶数据的下一个位置pst->top = 0; top指向栈顶数据//pst->top = -1;
}void STDestroy(ST* pst)
{assert(pst);free(pst->a);pst->a = NULL;pst->capacity = 0;pst->top = 0;
}void STPush(ST* pst, STDataType x)
{assert(pst);//扩容if (pst->top == pst->capacity){int newcapacity = (pst->capacity == 0) ? 4 : (2 * pst->capacity);STDataType* tmp = (STDataType*)realloc(pst->a, newcapacity * sizeof(STDataType));if (tmp == NULL){perror("realloc failed");exit(1);}pst->a = tmp;pst->capacity = newcapacity;}//存放数据pst->a[pst->top] = x;pst->top++;
}void STPop(ST* pst)
{assert(pst);assert(pst->top > 0);pst->top--;
}STDataType STTop(ST* pst)
{assert(pst);assert(pst->top > 0);return pst->a[pst->top - 1];
}_Bool STEmpty(ST* pst)
{assert(pst);return pst->top == 0;
}int STSize(ST* pst)
{assert(pst);return pst->top;
}typedef struct
{ST s1;ST s2;
} MyQueue;MyQueue* myQueueCreate()
{MyQueue* pqe = (MyQueue*)malloc(sizeof(MyQueue));if(pqe == NULL){perror("malloc failed");exit(1);}STInit(&(pqe->s1));STInit(&(pqe->s2));return pqe;
}void myQueuePush(MyQueue* obj, int x)
{if(!STEmpty(&(obj->s1))){STPush(&(obj->s1), x);}else{STPush(&(obj->s2), x);}
}int myQueuePop(MyQueue* obj)
{ST* emp = &(obj->s1);//假设s1为空ST* noemp = &(obj->s2);if (STEmpty(&(obj->s2)))//如果s2为空{emp = &(obj->s2);noemp = &(obj->s1);}int sz = STSize(noemp);if (sz == 1){int top = STTop(noemp);STPop(noemp);return top;}else{while (sz > 1){STPush(emp, STTop(noemp));STPop(noemp);sz--;}int top = STTop(noemp);STPop(noemp);ST* tmp = noemp;noemp = emp;emp = tmp;sz = STSize(noemp);while (sz > 0){STPush(emp, STTop(noemp));STPop(noemp);sz--;}return top;}
}int myQueuePeek(MyQueue* obj)
{ST* emp = &(obj->s1);//假设s1为空ST* noemp = &(obj->s2);if (STEmpty(&(obj->s2)))//如果s2为空{emp = &(obj->s2);noemp = &(obj->s1);}int sz = STSize(noemp);if (sz == 1){int top = STTop(noemp);return top;}else{while (sz > 1){STPush(emp, STTop(noemp));STPop(noemp);sz--;}int top = STTop(noemp);STPush(emp, STTop(noemp));STPop(noemp);ST* tmp = noemp;noemp = emp;emp = tmp;sz = STSize(noemp);while (sz > 0){STPush(emp, STTop(noemp));STPop(noemp);sz--;}return top;}
}bool myQueueEmpty(MyQueue* obj)
{return STEmpty(&obj->s1) && STEmpty(&obj->s2);
}void myQueueFree(MyQueue* obj)
{STDestroy(&obj->s1);STDestroy(&obj->s2);free(obj);
}/*** Your MyQueue struct will be instantiated and called as such:* MyQueue* obj = myQueueCreate();* myQueuePush(obj, x);* int param_2 = myQueuePop(obj);* int param_3 = myQueuePeek(obj);* bool param_4 = myQueueEmpty(obj);* myQueueFree(obj);
*/
四. 概念选择题
- 循环队列的存储空间为 Q(1:100) ,初始状态为front=rear=100 。经过一系列正常的入队与退队操作后, front=rear=99 ,则循环队列中的元素个数为( )
A 1
B 2
C 99
D 0或者100 - 以下( )不是队列的基本运算?
A 从队尾插入一个新元素
B 从队列中删除第i个元素
C 判断一个队列是否为空
D 读取队头元素的值 - 现有一循环队列,其队头指针为front,队尾指针为rear;循环队列长度为N。其队内有效长度为?(假设队头不存放数据)
A (rear - front + N) % N + 1
B (rear - front + N) % N
C ear - front) % (N + 1)
D (rear - front + N) % (N - 1)
答案 - D
- B
- B
五. 参考代码
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 val;
}QNode;typedef struct Queue
{QNode* phead; QNode* ptail;int size;
}Queue;队尾插入
//void QueuePush(QNode** pphead, QNode** pptail, QDataType x);
//
队头删除
//void QueuePop(QNode** pphead, QNode** pptail);//初始化
void QueueInit(Queue* pq);//队尾插入
void QueuePush(Queue* pq, QDataType x);//队头删除
void QueuePop(Queue* pq);//取队头数据
QDataType QueueFront(Queue* pq);//取队尾数据
QDataType QueueBack(Queue* pq);//队列元素个数
int QueueSize(Queue* pq);//判空
_Bool QueueEmpty(Queue* pq);//队列的销毁
void QueueDestroy(Queue* pq);
Queue.c
#include "Queue.h"void QueueInit(Queue* pq)
{assert(pq);pq->phead = NULL;pq->ptail = NULL;pq->size = 0;
}void QueuePush(Queue* pq, QDataType x)
{QNode* newnode = (QNode*)malloc(sizeof(QNode));if (newnode == NULL){perror("malloc failed");exit(1);}newnode->next = NULL;newnode->val = x;if (pq->ptail == NULL){pq->phead = newnode;pq->ptail = newnode;}else{pq->ptail->next = newnode;pq->ptail = newnode;}pq->size++;
}void QueuePop(Queue* pq)
{assert(pq);assert(pq->size);QNode* next = pq->phead->next;free(pq->phead);pq->phead = next;if (pq->phead == NULL)//just one node{pq->ptail = NULL;}pq->size--;
}QDataType QueueFront(Queue* pq)
{assert(pq);assert(pq->phead);return pq->phead->val;
}QDataType QueueBack(Queue* pq)
{assert(pq);assert(pq->ptail);return pq->ptail->val;
}int QueueSize(Queue* pq)
{assert(pq);return pq->size;
}_Bool QueueEmpty(Queue* pq)
{assert(pq);return pq->size == 0;
}void QueueDestroy(Queue* pq)
{assert(pq);QNode* pcur = pq->phead;while (pcur){QNode* next = pcur->next;free(pcur);pcur = next;}pq->phead = NULL;pq->ptail = NULL;pq->size = 0;
}
test.c
#include "Queue.h"int main()
{Queue q;QueueInit(&q);QueuePush(&q, 1);QueuePush(&q, 2);QueuePush(&q, 3);QueuePush(&q, 4);QueuePush(&q, 5);while (!QueueEmpty(&q)){printf("%d ", QueueFront(&q));QueuePop(&q);}return 0;
}
相关文章:

C语言实现数据结构之队列
目录 队列一. 队列的概念及结构二. 队列的实现1. 要实现的功能2 具体的实现2.1 结构体2.2 初始化2.3 入队列2.4 出队列2.5 返回队首元素2.6 返回队尾元素2.7 队列元素个数2.8 队列判空2.9 队列销毁 三. 队列相关OJ题设计循环队列用队列实现栈用栈实现队列 四. 概念选择题五. 参…...

写一个Vue2和vue3的自定义指令(以复制指定作为示例)
文章目录 一、自定义指令是什么?二、自定义指令有啥用?三、自定义指令怎么用?1.自定义指令的参数2.自定义指令的钩子函数(1)五个钩子函数的说明(2)钩子函数的参数(主要参数:el和valu…...

MySQL —— 聚合查询,分组查询 与 联合查询
聚合函数 常见的统计总数、计算平局值等操作,可以使用聚合函数来实现,常见的聚合函数有: 函数说明count()统计数据总数sum()求和avg()求平均值max()求最大值min()求最小值 注意凡是涉及运算的,数据库会自动掉 NULL 值 注意NULL …...

Spring声明式事务失效场景
Spring声明式事务失效场景 背景搭建测试环境测试事务失效场景Transactional 注解标注在 private 方法上异常被 catch 了,事务失效方法抛出的是受检异常,事务也会失效事务传播行为配置不合理导致事务失效 背景 Spring 针对 Java Transaction API (JTA)、…...

基于SpringBoot+UniAPP宠物食品外卖点单小程序的设计与实现》
✅博主简介:Java 全栈开发工程师,抖音优质技术创作者,日常分享实用的前端、后端、运维开发技术。 ✅技术栈:Java、SpringBoot、Vue、React、Node.js、Nest.js、Nuxt.js、uni-app ✅技术擅长:计算机毕设选题、开题报告、…...
ssrf 内网访问 伪协议 读取文件 端口扫描
SSRF(Server-Side Request Forgery,服务器侧请求伪造)是一种利用服务器发起网络请求的能力来攻击内网资源或执行其他恶意活动的技术。SSRF可以用于访问通常不可由外部直接访问的内网资源,读取文件,甚至进行端口扫描。以…...

发布包到npm
目录 注册npm账号 创建包 登录npm 上架包 更新包 删除包 注册npm账号 首先注册npm账号:npm | Sign Up (npmjs.com) 创建包 可以在桌面上新建一个文件夹:文件夹名随便起,但是别跟npm已经上架的包名重复了 可以通过下面的指令查看&…...

Python | Leetcode Python题解之第324题摆动排序II
题目: 题解: def quickSelect(a: List[int], k: int) -> int:seed(datetime.datetime.now())shuffle(a)l, r 0, len(a) - 1while l < r:pivot a[l]i, j l, r 1while True:i 1while i < r and a[i] < pivot:i 1j - 1while j > l an…...

IGModel——提高基于 GNN与Attention 机制的方法在药物发现中的实用性
导言 深度学习在药物发现(发现治疗药物)领域的应用以及传统方法面临的挑战。 药物(尤其是我们将在本文中讨论的被称为抑制剂的药物)通过与在人体中发挥不良功能的蛋白质结合并改变这些蛋白质的功能来发挥治疗效果。因此…...

AArch64中的寄存器
目录 通用寄存器 其他寄存器 系统寄存器 通用寄存器 大多数A64指令在寄存器上操作。该架构提供了31个通用寄存器。 每个寄存器可以作为64位的X寄存器(X0..X30)使用,或者作为32位的W寄存器(W0..W30)使用。这两种是查…...

树莓派Pico 2来了
这两天开源圈的大事之一,就是树莓派基金会发布了树莓派Pico 2。 帖子原文:Raspberry Pi Pico 2, our new $5 microcontroller board, on sale now 总结一些关键信息: 产品发布:Raspberry Pi Pico 2 是 Raspberry Pi 基金会推出的…...
LeetCode面试题Day7|LeetCode135 分发糖果、LeetCode42 接雨水
题目1: 指路: . - 力扣(LeetCode)135 分发糖果 思路与分析: 给n个孩子按照评分给糖果,要求有二,其一为每个孩子最少有一颗糖果;其二为相邻孩子评分更高的糖果越多。那么在这里第…...

[免费]适用于 Windows 10 的十大数据恢复软件
Windows 10 是 Microsoft 开发的跨平台和设备应用程序操作系统。它启动速度更快,具有熟悉且扩展的“开始”菜单,甚至可以在多台设备上以新的方式工作。因此,Windows 10 非常受欢迎,我们用它来保存照片、音乐、文档和更多文件。但有…...

Win11+docker+vscode配置anomalib并训练自己的数据(3)
在前两篇博文中,我使用Win11+docker配置了anomalib,并成功的调用了GPU运行了示例程序。这次我准备使用anomalib训练我自己的数据集。 数据集是我在工作中收集到的火腿肠缺陷数据,与MVTec等数据不同,我的火腿肠数据来源于多台设备和多个品种,因此,它们表面的纹理与颜色差异…...

Java | Leetcode Java题解之第332题重新安排行程
题目: 题解: class Solution {Map<String, PriorityQueue<String>> map new HashMap<String, PriorityQueue<String>>();List<String> itinerary new LinkedList<String>();public List<String> findItine…...
招聘公告|健安环保科技(广东)有限公司
招聘岗位:销售经理 岗位职责: 对PCB线路板和电镀行业的客户,推广针对镀锡漂洗水的低浓度锡回收技术(投资运营或设备销售),并销售无耗材材的电镀智能过滤设备,达成销售目标; 任职要求: 1、大专以上学历&…...
小程序的安全设计
小程序的安全设计 安全指引 | 微信开放文档 (qq.com) 开发原则与注意事项 本文档整理了部分小程序开发中常见的安全风险和漏洞,用于帮助开发者在开发环节中发现和修复相关漏洞,避免在上线后对业务和数据造成损失。 开发者在开发环节中必须基于以下原则: 互不信任原则,不要…...

【Android】网络技术知识总结之WebView,HttpURLConnection,OKHttp,XML的pull解析方式
文章目录 webView使用步骤示例 HttpURLConnection使用步骤示例GET请求POST请求 okHttp使用步骤1. 添加依赖2. 创建OkHttpClient实例3. 创建Request对象构建请求4. 发送请求5. 获取响应 Pull解析方式1. 准备XML数据2. 创建数据类3. 使用Pull解析器解析XML webView WebView 是 An…...

Kubernetes—k8s集群存储卷(pvc存储卷)
目录 一、PVC 和 PV 1.PV 2.PVC 3.StorageClass 4.PV和PVC的生命周期 二、实操 1.创建静态pv 1.配置nfs 2.创建pv 3.创建pvc 4.结合pod,将pv、pvc一起运行 2.创建动态pv 1.上传 2.创建 Service Account,用来管理 NFS Provisioner 在 k8s …...
用网格大师转换的3D Tiles数据,在进行了顶点重建后,尝试加载到Cesium中却无法显示内容。应该如何解决这一问题?
答: 建议首先尝试使用DasViewer来打开并检查这个3D Tiles的json文件。DasViewer能够迅速加载并显示3D Tiles数据,可以帮助快速验证数据是否完整且格式正确。 网格大师是一款能够解决实景三维模型空间参考、原点、瓦块大小不统一,重叠区域处理…...

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型
摘要 拍照搜题系统采用“三层管道(多模态 OCR → 语义检索 → 答案渲染)、两级检索(倒排 BM25 向量 HNSW)并以大语言模型兜底”的整体框架: 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后,分别用…...

XCTF-web-easyupload
试了试php,php7,pht,phtml等,都没有用 尝试.user.ini 抓包修改将.user.ini修改为jpg图片 在上传一个123.jpg 用蚁剑连接,得到flag...
golang循环变量捕获问题
在 Go 语言中,当在循环中启动协程(goroutine)时,如果在协程闭包中直接引用循环变量,可能会遇到一个常见的陷阱 - 循环变量捕获问题。让我详细解释一下: 问题背景 看这个代码片段: fo…...
django filter 统计数量 按属性去重
在Django中,如果你想要根据某个属性对查询集进行去重并统计数量,你可以使用values()方法配合annotate()方法来实现。这里有两种常见的方法来完成这个需求: 方法1:使用annotate()和Count 假设你有一个模型Item,并且你想…...

ESP32 I2S音频总线学习笔记(四): INMP441采集音频并实时播放
简介 前面两期文章我们介绍了I2S的读取和写入,一个是通过INMP441麦克风模块采集音频,一个是通过PCM5102A模块播放音频,那如果我们将两者结合起来,将麦克风采集到的音频通过PCM5102A播放,是不是就可以做一个扩音器了呢…...

2025盘古石杯决赛【手机取证】
前言 第三届盘古石杯国际电子数据取证大赛决赛 最后一题没有解出来,实在找不到,希望有大佬教一下我。 还有就会议时间,我感觉不是图片时间,因为在电脑看到是其他时间用老会议系统开的会。 手机取证 1、分析鸿蒙手机检材&#x…...

12.找到字符串中所有字母异位词
🧠 题目解析 题目描述: 给定两个字符串 s 和 p,找出 s 中所有 p 的字母异位词的起始索引。 返回的答案以数组形式表示。 字母异位词定义: 若两个字符串包含的字符种类和出现次数完全相同,顺序无所谓,则互为…...
HTML前端开发:JavaScript 常用事件详解
作为前端开发的核心,JavaScript 事件是用户与网页交互的基础。以下是常见事件的详细说明和用法示例: 1. onclick - 点击事件 当元素被单击时触发(左键点击) button.onclick function() {alert("按钮被点击了!&…...

初学 pytest 记录
安装 pip install pytest用例可以是函数也可以是类中的方法 def test_func():print()class TestAdd: # def __init__(self): 在 pytest 中不可以使用__init__方法 # self.cc 12345 pytest.mark.api def test_str(self):res add(1, 2)assert res 12def test_int(self):r…...
Mobile ALOHA全身模仿学习
一、题目 Mobile ALOHA:通过低成本全身远程操作学习双手移动操作 传统模仿学习(Imitation Learning)缺点:聚焦与桌面操作,缺乏通用任务所需的移动性和灵活性 本论文优点:(1)在ALOHA…...