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

数据结构:栈和队列(Leetcode20. 有效的括号+225. 用队列实现栈+232. 用栈实现队列)

目录

一.数据结构--栈

1.栈的基本介绍

2.栈的实现

二.数据结构--队列

1.队列的基本介绍

2.队列的实现 

三.栈的运用(Leetcode20. 有效的括号+225) 

1.问题描述 

2.问题分析

题解代码:

四.用两个队列实现栈(225. 用队列实现栈 - 力扣(Leetcode))

题解代码:

五.用两个栈实现队列(232. 用栈实现队列 - 力扣(Leetcode))

​题解代码:


一.数据结构--栈

1.栈的基本介绍

栈是一种数据先进后出,后进先出的数据结构:

  • 栈一般用数组来实现(用单链表实现的栈缺陷明显:数据的出栈操作时间复杂度为O(N),原因在于要找到表尾数据的前一个数据的地址

2.栈的实现

总体图解:

栈的头文件:

#pragma once
#include <stdio.h>
#include <assert.h>
#include <stdbool.h>
#include <stdlib.h>typedef int STDataType;
typedef struct Stack
{STDataType * arry;	   //栈的堆区空间指针int top;               //维护栈顶下标,同时记录栈中的元素个数int capacity;		   //记录栈的容量
}ST;void StackInit(ST* Stack);					//栈对象的初始化
STDataType StackTop(ST*Stack);				//返回栈顶元素
void StackPush(ST* Stack,STDataType val);   //元素入栈
void StackPop(ST* Stack);					//元素出栈
int StackSize(ST* Stack);				    //返回栈对的元素个数的接口;
bool StackEmpty(ST* Stack);					//判断栈是否为空的接口
void StackDestroy(ST* Stack);				//销毁栈

栈初始化接口:

void StackInit(ST* Stack)
{assert(Stack);Stack->arry = NULL;Stack->capacity = 0;Stack->top = 0;
}

返回栈顶元素的接口:

STDataType StackTop(ST* Stack)
{assert(Stack);assert(Stack->top > 0);return Stack->arry[Stack->top - 1];
}

返回栈数据个数的接口:

int StackSize(ST* Stack)
{assert(Stack);return Stack->top;
}

判断栈是否为空的接口:

bool StackEmpty(ST* Stack)
{assert(Stack);return (Stack->top == 0);
}

数据入栈操作接口:

void StackPush(ST* Stack, STDataType val)
{assert(Stack);if (Stack->capacity == Stack->top)    //检查容量是否足够{int newcapacity = (0 == Stack->capacity) ? 4 : 2 * Stack->capacity;//如果容量为零,则将容量设置为4,其他情况下按照两倍扩容方式增容STDataType* tem = (STDataType*)realloc(Stack->arry, newcapacity*sizeof(STDataType));if (NULL == tem)//判断realloc是否成功{perror("realloc failed:");exit(-1);}Stack->capacity = newcapacity;Stack->arry = tem;}//元素入栈Stack->arry[Stack->top] = val;Stack->top++;
}

数据出栈操作接口:

void StackPop(ST* Stack)
{assert(Stack);assert(Stack->top > 0);Stack->top--;
}

销毁栈的接口:

void StackDestroy(ST* Stack)
{assert(Stack);if (Stack->arry){free(Stack->arry);}Stack->arry = NULL;Stack->capacity = 0;Stack->top = 0;
}

二.数据结构--队列

1.队列的基本介绍

队列是一种数据先进先出,后进后出的数据结构.

  • 数据只能从队尾入,从队头出 
  • 队列一般用单链表实现,原因在于队列涉及数据的头删操作,单链表的数据头删操作时间复杂度为O(1).

2.队列的实现 

队列总体图解:

队列的头文件: 

#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <assert.h>typedef int QDataType;typedef struct QueueNode         //单链表结构体
{struct QueueNode* next;QDataType data;
}QNode;typedef struct Queue             //维护队列的结构体
{QNode* head;QNode* tail;
}Queue;void QueueInit(Queue* queue);                  //队列的初始化接口
void QueueDestroy(Queue* queue);               //销毁队列的接口
void QueuePush(Queue* queue,QDataType val);    //数据入队接口
void QueuePop(Queue* queue);                   //数据出队接口
QDataType QueueFront(Queue* queue);            //返回队头数据接口
QDataType QueueBawck(Queue* queue);            //返回队尾数据接口
int QueueSize(Queue* queue);                   //返回队列数据个数的接口
bool QueueEmpty(Queue* queue);                 //判断队列是否为空的接口

队列的初始化接口:

void QueueInit(Queue* queue)       //队列初始化   
{assert(queue);queue->head = NULL;queue->tail = NULL;
}

返回队头数据的接口:

QDataType QueueFront(Queue* queue) //返回队列头部数据
{assert(queue);assert(queue->head);return queue->head->data;
}

返回队尾数据的接口:

QDataType QueueBawck(Queue* queue) //返回队列尾部数据
{assert(queue);assert(queue->tail);return queue->tail->data;
}

返回队列数据个数的接口:

int QueueSize(Queue* queue)        //返回队列节点个数
{assert(queue);int count = 0;QNode* tem = queue->head;while(tem){count++;tem = tem->next;}return count;
}

判断队列是否为空的接口:

bool QueueEmpty(Queue* queue)      //判断队列是否为空
{assert(queue);return (NULL == queue->head);
}

数据入队接口:

  

void QueuePush(Queue* queue,QDataType val)         //链表尾插数据(数据从队列尾入队)
{assert(queue);QNode* NewNode = (QNode*)malloc(sizeof(QNode));//申请堆区链表节点if (NULL == NewNode){perror("malloc failed:");exit(-1);}NewNode->data = val;NewNode->next = NULL;if (NULL == queue->tail)                       //链表为空时的数据插入操作{assert(NULL == queue->head);queue->tail = NewNode;queue->head = NewNode;}else                                           //链表非空时的数据插入操作{queue->tail->next = NewNode;queue->tail = NewNode;}
}

数据出队的接口:

void QueuePop(Queue* queue)		    //删去链表头节点(数据从队列头部出队)
{assert(queue);assert(queue->head && queue->tail);QNode* Next = queue->head->next;free(queue->head);queue->head = Next;if (NULL == queue->head)        //若删去的是链表的最后一个元素,则要将尾指针也置空{queue->tail = NULL;}
}

销毁队列的接口:

void QueueDestroy(Queue* queue)    //销毁链表(队列)
{assert(queue);QNode* tem = queue->head;while (tem){QNode* Next = tem->next;free(tem);tem = Next;}queue->head = NULL;queue->head = NULL;
}

三.栈的运用(Leetcode20. 有效的括号+225) 

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

1.问题描述 

 

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

有效字符串需满足:

  1. 左括号必须用相同类型的右括号闭合。
  2. 左括号必须以正确的顺序闭合。
  3. 每个右括号都有一个对应的相同类型的左括号。

示例:

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

C题解接口:

bool isValid(char * s)
{}

2.问题分析

左向右遍历字符串的情况下的括号匹配思路:

  • 由于在遍历字符串时,我们无法确定当前的左括号会和哪一个右括号匹配,因此匹配的思路应该是先找到第一个右括号,然后再向前寻找相应的左括号,若匹配失败则返回false,若匹配成功则继续寻找下一个右括号重复上述过程,直到结束
  •  暴力匹配算法动画解析:
  • 根据上面的分析可知暴力匹配法的时间复杂度为O(N^2) 

然而本题如果使用辅助栈来求解,则可以达到用空间来换取时间效率的目的。

基本思路如下:

  • 用一个指针遍历字符串,每当遇到左括号,我们就将其压入栈中
  • 每当遇到右括号,我们就将其与栈顶括号进行匹配,若匹配失败则说明字符串不满足条件,接口返回false,若匹配成功则弹出栈顶元素,并继续遍历字符串重复上述步骤直到找到'\0'则接口返回true
  • 算法动画图解: 

我们可以将实现好的栈(本期第一节中)用于解题(顺便还可以验证我们栈的实现有没有bug)

题解代码:

用于题解的栈:

typedef char STDataType;
typedef struct Stack
{STDataType * arry;	   //栈的堆区空间指针int top;               //维护栈顶下标,同时记录栈中的元素个数int capacity;		   //记录栈的容量
}ST;void StackInit(ST* Stack)
{assert(Stack);Stack->arry = NULL;Stack->capacity = 0;Stack->top = 0;
}STDataType StackTop(ST* Stack)
{assert(Stack);assert(Stack->top > 0);return Stack->arry[Stack->top - 1];
}void StackPush(ST* Stack, STDataType val)
{assert(Stack);if (Stack->capacity == Stack->top)    //检查容量是否足够{int newcapacity = (0 == Stack->capacity) ? 4 : 2 * Stack->capacity;STDataType* tem = (STDataType*)realloc(Stack->arry, newcapacity*sizeof(STDataType));if (NULL == tem){perror("realloc failed:");exit(-1);}Stack->capacity = newcapacity;Stack->arry = tem;}Stack->arry[Stack->top] = val;Stack->top++;
}void StackPop(ST* Stack)
{assert(Stack);assert(Stack->top > 0);Stack->top--;
}int StackSize(ST* Stack)
{assert(Stack);return Stack->top;
}bool StackEmpty(ST* Stack)
{assert(Stack);return (Stack->top == 0);
}void StackDestroy(ST* Stack)
{assert(Stack);if (Stack->arry){free(Stack->arry);}Stack->arry = NULL;Stack->capacity = 0;Stack->top = 0;
}

两个辅助判断接口代码:

    //判断指针指向的括号是否为右括号的接口bool CheckRightQutoe(const char quote)  //左括号返回true,有括号返回false{if('{' == quote || '(' == quote || '[' == quote){return true;}else{return false;}}
    //判断两个括号是否匹配的接口bool JudgeMatch(const char right,const char left){if(('}' == right && '{' == left) || (']' == right && '[' == left) || (')' == right && '(' == left) ){return true;}return false;}

题解接口代码:

bool isValid(char * s)
{ST ans;StackInit(&ans);         //创建一个栈int lenth = strlen(s);   //字符串有效字符个数为奇数直接返回falseif(lenth % 2 == 1)       {return false;}char * tem = s;          //tem用于遍历字符串while('\0' != *tem){if(CheckRightQutoe(*tem))  //遇到右括号则入栈{StackPush(&ans,*tem);}else                       //遇到左括号则与栈顶右括号匹配{if(StackEmpty(&ans) || !JudgeMatch(*tem,StackTop(&ans))){return false;      //匹配前注意判断栈是否为空}StackPop(&ans);        //匹配完后弹出栈顶括号       }tem ++;}if(!StackEmpty(&ans))          //栈为空说明全部括号都完成了匹配{return false;}return true;
}
  • 该方法充分利用了栈数据后进先出的特点
  • 算法的时间复杂度为O(N)

 

四.用两个队列实现栈(225. 用队列实现栈 - 力扣(Leetcode))

本题并没有什么实际意义,求解它的目的仅仅在于加深对栈和队列这两种数据结构的理解

  • 用两个队列实现数据的先进后出

题解接口:

typedef struct 
{} MyStack;//创建MyStack结构体
MyStack* myStackCreate() 
{}//向MyStack两个队列成员中的非空队列中插入数据
//(若两个队列都为空则向任意一个队列插入数据都可以)
void myStackPush(MyStack* obj, int x) 
{}//删除栈顶元素(同时返回栈顶元素的值)
int myStackPop(MyStack* obj) 
{}//栈顶的数据其实就是非空队列尾的数据
int myStackTop(MyStack* obj) 
{}//返回栈顶的数据
bool myStackEmpty(MyStack* obj) 
{}//销毁栈
void myStackFree(MyStack* obj) 
{}

我们可以给自己设置一个规定:用队列实现的'栈'的接口中,我们只能使用队列的标准操作接口来操作'栈'中的元素的进出.

  • 本题我们利用本期第二节实现好的队列来实现栈

用两个队列实现栈的数据结构总体图解:

两个队列实现一个栈的结构体的定义:

typedef struct 
{Queue queue1;Queue queue2;
} MyStack;

数据入'栈'接口:

void myStackPush(MyStack* obj, int x) 
  • 向MyStack两个队列成员中的非空队列中插入数据
  • (若两个队列都为空则向任意一个队列插入数据都可以) 
//向MyStack两个队列成员中的非空队列中插入数据
//(若两个队列都为空则向任意一个队列插入数据都可以)
void myStackPush(MyStack* obj, int x) 
{if(!QueueEmpty(&(obj->queue1))){QueuePush(&(obj->queue1),x);}else{QueuePush(&(obj->queue2),x);}
}

数据出栈接口:

int myStackPop(MyStack* obj) 


数据出栈过程动画图解:

 

//删除栈顶元素(同时返回栈顶元素的值)
int myStackPop(MyStack* obj) 
{int ret = 0;//将非空队列里面的(除了队尾的元素)移到另外一个空队列中if(!QueueEmpty(&(obj->queue1)) && QueueEmpty(&(obj->queue2))){while(obj->queue1.head != obj->queue1.tail) //转移数据{QueuePush(&(obj->queue2),(obj->queue1).head->data);QueuePop(&(obj->queue1));               }ret = QueueFront(&(obj->queue1));   //记录要弹出的数据QueuePop(&(obj->queue1));           //弹出数据}else{while(obj->queue2.head != obj->queue2.tail) //转移数据{QueuePush(&(obj->queue1),(obj->queue2).head->data);QueuePop(&(obj->queue2));}ret = QueueFront(&(obj->queue2));    //记录要弹出的数据QueuePop(&(obj->queue2));            //弹出数据}return ret;                              //返回被弹出的数据
}
  • 通过两个队列的交互我们便完成了数据的先进后出

题解代码:

用于题解的队列:

typedef int QDataType;typedef struct QueueNode      //队列链表节点结构体
{struct QueueNode* next;QDataType data;
}QNode;typedef struct Queue          //维护队列的结构体
{QNode* head;QNode* tail;
}Queue;void QueueInit(Queue* queue);               //队列初始化
void QueueDestroy(Queue* queue);            //销毁链表(队列)
void QueuePush(Queue* queue,QDataType val); //链表尾插数据(数据从队列尾入队)
void QueuePop(Queue* queue);                //删去链表头节点(数据从队列头部出队)
QDataType QueueFront(Queue* queue);         //返回队列头部数据
QDataType QueueBawck(Queue* queue);         //返回队列尾部数据
int QueueSize(Queue* queue);                //返回队列节点个数
bool QueueEmpty(Queue* queue);              //判断队列是否为空void QueueInit(Queue* queue)       //队列初始化   
{assert(queue);queue->head = NULL;queue->tail = NULL;
}
void QueueDestroy(Queue* queue)    //销毁链表(队列)
{assert(queue);QNode* tem = queue->head;while (tem)                    //逐个节点释放链表{QNode* Next = tem->next;free(tem);tem = Next;}queue->head = NULL;queue->head = NULL;
}void QueuePush(Queue* queue,QDataType val)  //链表尾插数据(数据从队列尾入队)
{assert(queue);QNode* NewNode = (QNode*)malloc(sizeof(QNode));if (NULL == NewNode)                    //在堆区申请节点空间{perror("malloc failed:");exit(-1);}NewNode->data = val;NewNode->next = NULL;if (NULL == queue->tail)                //注意判断队列是否为空队列并分类讨论完成元素插入{assert(NULL == queue->head);queue->tail = NewNode;              //队列为空时tail和head指向同一个节点queue->head = NewNode;}else{queue->tail->next = NewNode;        //队列非空时令tail指向队尾数据queue->tail = NewNode;}
}void QueuePop(Queue* queue)		    //删去链表头节点(数据从队列头部出队)
{assert(queue);assert(queue->head && queue->tail);QNode* Next = queue->head->next;free(queue->head);queue->head = Next;if (NULL == queue->head)        //注意判断完成删除元素后队列是否变为空队列{queue->tail = NULL;}
}QDataType QueueFront(Queue* queue) //返回队列头部数据
{assert(queue);assert(queue->head);return queue->head->data;
}
QDataType QueueBawck(Queue* queue) //返回队列尾部数据
{assert(queue);assert(queue->tail);return queue->tail->data;
}int QueueSize(Queue* queue)        //返回队列节点个数
{assert(queue);int count = 0;QNode* tem = queue->head;while(tem)                      //计算节点个数{count++;tem = tem->next;}return count;
}bool QueueEmpty(Queue* queue)      //判断队列是否为空
{assert(queue);return (NULL == queue->head);
}

题解的栈:

typedef struct 
{Queue queue1;Queue queue2;
} MyStack;//创建MyStack结构体
MyStack* myStackCreate() 
{MyStack * tem = (MyStack *)malloc(sizeof(MyStack));if(NULL == tem){perror("malloc failed:");exit(-1);}QueueInit(&(tem->queue1));QueueInit(&(tem->queue2));return tem;
}//向MyStack两个队列成员中的非空队列中插入数据
//(若两个队列都为空则向任意一个队列插入数据都可以)
void myStackPush(MyStack* obj, int x) 
{if(!QueueEmpty(&(obj->queue1))){QueuePush(&(obj->queue1),x);}else{QueuePush(&(obj->queue2),x);}
}//删除栈顶元素(同时返回栈顶元素的值)
int myStackPop(MyStack* obj) 
{int ret = 0;//将非空队列里面的(除了队尾的元素)移到另外一个空队列中if(!QueueEmpty(&(obj->queue1)) && QueueEmpty(&(obj->queue2))){while(obj->queue1.head != obj->queue1.tail) //转移数据{QueuePush(&(obj->queue2),(obj->queue1).head->data);QueuePop(&(obj->queue1));               }ret = QueueFront(&(obj->queue1));   //记录要弹出的数据QueuePop(&(obj->queue1));           //弹出数据}else{while(obj->queue2.head != obj->queue2.tail) //转移数据{QueuePush(&(obj->queue1),(obj->queue2).head->data);QueuePop(&(obj->queue2));}ret = QueueFront(&(obj->queue2));    //记录要弹出的数据QueuePop(&(obj->queue2));            //弹出数据}return ret;                              //返回被弹出的数据
}//栈顶的数据其实就是非空队列尾的数据
int myStackTop(MyStack* obj) 
{if(!QueueEmpty(&(obj->queue1))){return obj->queue1.tail->data;}else{return obj->queue2.tail->data;}
}//返回栈顶的数据
bool myStackEmpty(MyStack* obj) 
{return QueueEmpty(&(obj->queue1)) && QueueEmpty(&(obj->queue2));
}//销毁栈
void myStackFree(MyStack* obj) 
{QueueDestroy(&(obj->queue1));QueueDestroy(&(obj->queue2));free(obj);obj = NULL;
}

五.用两个栈实现队列(232. 用栈实现队列 - 力扣(Leetcode))

思路图解:

 题解代码:

typedef struct 
{ST PushStack;ST PopStack;   
} MyQueue;MyQueue* myQueueCreate()    //队列初始化接口
{MyQueue* tem = (MyQueue *)malloc(sizeof(MyQueue));if(NULL == tem){perror("malloc failed:");exit(-1);}StackInit(&(tem->PushStack));StackInit(&(tem->PopStack));return tem;
}void myQueuePush(MyQueue* obj, int x) 
{StackPush(&(obj->PushStack),x);//数据入队
}int myQueuePop(MyQueue* obj) 
{assert(!StackEmpty(&(obj->PushStack)) || !StackEmpty(&(obj->PopStack)));//数据出队前保证队列不为空if(StackEmpty(&(obj->PopStack)))  //PopStack为空则要将PushStack数据转移进来{while(!StackEmpty(&(obj->PushStack))){StackPush(&(obj->PopStack),StackTop(&(obj->PushStack)));//将PushStack栈顶数据压入PopStack栈中StackPop(&(obj->PushStack));//完成数据转移后弹出PushStack的栈顶数据}}int ret = StackTop(&(obj->PopStack)); //记录队头元素StackPop(&(obj->PopStack));           //元素出队return ret;                           //返回队头元素
}int myQueuePeek(MyQueue* obj) 
{assert(!StackEmpty(&(obj->PushStack)) || !StackEmpty(&(obj->PopStack)));//保证队列不为空if(StackEmpty(&(obj->PopStack))) //PopStack为空则要将PushStack数据转移进来{while(!StackEmpty(&(obj->PushStack))){StackPush(&(obj->PopStack),StackTop(&(obj->PushStack)));//将PushStack栈顶数据压入PopStack栈中StackPop(&(obj->PushStack));//完成数据转移后弹出PushStack的栈顶数据}}return StackTop(&(obj->PopStack));//返回PopStack栈顶元素作为队列队头元素
}bool myQueueEmpty(MyQueue* obj) 
{return StackEmpty(&(obj->PopStack))  && StackEmpty(&(obj->PushStack));//判断队列是否为空
}void myQueueFree(MyQueue* obj) 
{StackDestroy(&(obj->PopStack));StackDestroy(&(obj->PushStack));free(obj);obj = NULL;
}
  • 题解中我们运用的是本期第一节中实现好的栈

 

相关文章:

数据结构:栈和队列(Leetcode20. 有效的括号+225. 用队列实现栈+232. 用栈实现队列)

目录 一.数据结构--栈 1.栈的基本介绍 2.栈的实现 二.数据结构--队列 1.队列的基本介绍 2.队列的实现 三.栈的运用(Leetcode20. 有效的括号225) 1.问题描述 2.问题分析 题解代码&#xff1a; 四.用两个队列实现栈(225. 用队列实现栈 - 力扣&#xff08;Leetcode&a…...

22.2.19周赛双周赛(贪心、记忆化搜索...)

文章目录双周赛98[6359. 替换一个数字后的最大差值](https://leetcode.cn/problems/maximum-difference-by-remapping-a-digit/)[6361. 修改两个元素的最小分数](https://leetcode.cn/problems/minimum-score-by-changing-two-elements/)贪心排序[6360. 最小无法得到的或值](ht…...

2023最新软件测试面试题(带答案)

1. 请自我介绍一下(需简单清楚的表述自已的基本情况&#xff0c;在这过程中要展现出自信&#xff0c;对工作有激情&#xff0c;上进&#xff0c;好学) 面试官您好&#xff0c;我叫###&#xff0c;今年26岁&#xff0c;来自江西九江&#xff0c;就读专业是电子商务&#xff0c;毕…...

【C++】类型转换方法

本篇博客让我们来见识一下C中新增的类型转换方法 文章目录1.C语言中类型转换2.C中的强制类型转换2.1 static_cast2.2 reinterpret_cast2.3 const_castvolatile关键字2.4 dynamic_cast3.C强制类型转换的作用4.RTTI1.C语言中类型转换 在C语言中&#xff0c;类型转换有下面两种形…...

100亿级订单怎么调度,来一个大厂的极品方案

背景 超时处理&#xff0c;是一个很有技术难度的问题。 所以很多的小伙伴&#xff0c;在写简历的时候&#xff0c;喜欢把这个技术难题写在简历里边&#xff0c; 体现自己高超的技术水平。 在40岁老架构师 尼恩的读者交流群(50)中&#xff0c;尼恩经常指导大家 优化简历。 最…...

C++性能白皮书

最近看完了《C性能白皮书》&#xff0c;这本书列出了一些性能优化的思路&#xff0c;不过只是一些指引&#xff0c;没有讲具体细节&#xff0c;我整理出了其中的关键点分享给大家&#xff1a; 硬件篇 作为一个程序员&#xff0c;想要性能优化&#xff0c;最好要了解些硬件&…...

华为OD机试 - 黑板上色 | 机试题算法思路 【2023】

最近更新的博客 华为OD机试 - 简易压缩算法(Python) | 机试题算法思路 【2023】 华为OD机试题 - 获取最大软件版本号(JavaScript) 华为OD机试 - 猜字谜(Python) | 机试题+算法思路 【2023】 华为OD机试 - 删除指定目录(Python) | 机试题算法思路 【2023】 华为OD机试 …...

如何在六秒内吸引观众的注意力

根据《2022国民专注力洞察报告》显示&#xff0c;当代人的连续专注时长&#xff0c;已经从2000年的12秒&#xff0c;下降到了现在的8秒。对于这个事实你可能难以相信&#xff0c;实际上这意味着&#xff0c;大多数互联网用户跳到一些页面上时&#xff0c;可能眼皮都不眨一下就离…...

FreeRTOS与UCOSIII任务状态对比

FreeRTOS任务状态 1、运行态 正在运行的任务&#xff0c;正在使用处理器的任务。 单核处理器中任何时候都有且只有一个任务处于运行态。 2、就绪态 已经准备就绪&#xff08;非阻塞或挂起&#xff09;&#xff0c;可以立即运行但还没有运行的任务。 正在等待比自己高优先级…...

小程序 npm sill idealTree buildDeps 安装一直没反应

目录 一、问题 二、解决 1、删除.npmsrc 、清除缓存 2、更换镜像源 3、最终检测 一、问题 记录&#xff1a;今天npm 一直安装不成功 显示&#xff1a;sill idealTree buildDeps 我的版本&#xff1a; 我百度到换镜像源安装方法&#xff0c;但我尝试后&#xff0c;依然…...

GPT系列详解:初代GPT

本文详细解读了OpenAI公司在2018年6月发布的论文《Improving Language Understanding by Generative Pre-Training》&#xff0c;它其中介绍的算法也就是后来人们说的GPT。本文借鉴了李沐的这个视频&#xff0c;感兴趣的同学可以移步观看大神的讲解。 目录引言GPT方法无监督预训…...

为什么要使用数据库

数据保存在内存优点&#xff1a;存取速度快缺点&#xff1a;数据不能永久保存数据保存在文件优点&#xff1a;数据永久保存缺点&#xff1a;1&#xff09;速度比内存操作慢&#xff0c;频繁的IO操作。2&#xff09;查询数据不方便数据保存在数据库1&#xff09;数据永久保存2&a…...

【单目标优化算法】海鸥优化算法(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…...

筑基六层 —— 整型提升及实用调式技巧

目录 一.修炼必备 二. 整型提升 三.实用调式技巧 一.修炼必备 1.入门必备&#xff1a;VS2019社区版&#xff0c;下载地址&#xff1a;Visual Studio 较旧的下载 - 2019、2017、2015 和以前的版本 (microsoft.com) 2.趁手武器&#xff1a;印象笔记/有道云笔记 3.修炼秘籍&…...

后端前端文件传输2中传出模式

base64文件传输 app.route(/download, methods[get]) def hello_as(): # 数据 id request.args.get("id") cur g.db.cursor() cur.execute(fselect name,grade,commentNum,cityName,sceneryThemeName from dataList where cityId? , (id,)) …...

【ZOJ 1067】Color Me Less 题解(vector+开方)

问题 颜色缩减是从一组离散颜色到较小颜色的映射。这个问题的解决方案需要在标准的24位RGB颜色空间中执行这样的映射。输入由十六个RGB颜色值的目标集合和要映射到目标集合中最接近的颜色的任意RGB颜色集合组成。为了我们的目的&#xff0c;RGB颜色被定义为有序三元组&#xff…...

凌恩生物经典文章:孟德尔诞辰200周年,Nature Genetics礼献豌豆高质量精细图谱

本期为大家分享的文章是2022年发表在《Nature Genetics》上的一篇文章“Improved pea reference genome and pan-genome highlight genomic features and evolutionary characteristics”&#xff0c;作者通过结合三代pacbio测序、染色体构象捕获&#xff08;Hi-C&#xff09;测…...

进程间通信(二)/共享内存

⭐前言&#xff1a;在前面的博文中分析了什么的进程间通信和进程间通信的方式之一&#xff1a;管道&#xff08;匿名管道和命名管道&#xff09;。接下来分析第二种方式&#xff1a;共享内存。 要实现进程间通信&#xff0c;其前提是让不同进程之间看到同一份资源。所谓共享内存…...

电路模型和电路定律——“电路分析”

各位CSDN的uu们你们好呀&#xff0c;今天小雅兰的内容是我这学期的专业课噢&#xff0c;首先就学习了电路模型和电路定律&#xff0c;包括电路和电路模型、电流和电压的参考方向、电功率和能量、电路元件、电阻元件、电压源和电流源、基尔霍夫定律。那么现在&#xff0c;就让我…...

软件工程 | 第一章:软件工程学概述

软件工程学概述一、前言二、软件危机1.典型表现2.产生原因3.消除危机途径三、软件工程1.概述2.软件本质特征3.软件工程基本原理4.软件工程方法学1️⃣传统方法学2️⃣面向对象方法学四、软件生命周期五、结语一、前言 本文将讲述软件工程导论的第一章相关知识点&#xff0c;主…...

接口测试中缓存处理策略

在接口测试中&#xff0c;缓存处理策略是一个关键环节&#xff0c;直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性&#xff0c;避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明&#xff1a; 一、缓存处理的核…...

多云管理“拦路虎”:深入解析网络互联、身份同步与成本可视化的技术复杂度​

一、引言&#xff1a;多云环境的技术复杂性本质​​ 企业采用多云策略已从技术选型升维至生存刚需。当业务系统分散部署在多个云平台时&#xff0c;​​基础设施的技术债呈现指数级积累​​。网络连接、身份认证、成本管理这三大核心挑战相互嵌套&#xff1a;跨云网络构建数据…...

Vue记事本应用实现教程

文章目录 1. 项目介绍2. 开发环境准备3. 设计应用界面4. 创建Vue实例和数据模型5. 实现记事本功能5.1 添加新记事项5.2 删除记事项5.3 清空所有记事 6. 添加样式7. 功能扩展&#xff1a;显示创建时间8. 功能扩展&#xff1a;记事项搜索9. 完整代码10. Vue知识点解析10.1 数据绑…...

突破不可导策略的训练难题:零阶优化与强化学习的深度嵌合

强化学习&#xff08;Reinforcement Learning, RL&#xff09;是工业领域智能控制的重要方法。它的基本原理是将最优控制问题建模为马尔可夫决策过程&#xff0c;然后使用强化学习的Actor-Critic机制&#xff08;中文译作“知行互动”机制&#xff09;&#xff0c;逐步迭代求解…...

PPT|230页| 制造集团企业供应链端到端的数字化解决方案:从需求到结算的全链路业务闭环构建

制造业采购供应链管理是企业运营的核心环节&#xff0c;供应链协同管理在供应链上下游企业之间建立紧密的合作关系&#xff0c;通过信息共享、资源整合、业务协同等方式&#xff0c;实现供应链的全面管理和优化&#xff0c;提高供应链的效率和透明度&#xff0c;降低供应链的成…...

在 Nginx Stream 层“改写”MQTT ngx_stream_mqtt_filter_module

1、为什么要修改 CONNECT 报文&#xff1f; 多租户隔离&#xff1a;自动为接入设备追加租户前缀&#xff0c;后端按 ClientID 拆分队列。零代码鉴权&#xff1a;将入站用户名替换为 OAuth Access-Token&#xff0c;后端 Broker 统一校验。灰度发布&#xff1a;根据 IP/地理位写…...

OpenLayers 分屏对比(地图联动)

注&#xff1a;当前使用的是 ol 5.3.0 版本&#xff0c;天地图使用的key请到天地图官网申请&#xff0c;并替换为自己的key 地图分屏对比在WebGIS开发中是很常见的功能&#xff0c;和卷帘图层不一样的是&#xff0c;分屏对比是在各个地图中添加相同或者不同的图层进行对比查看。…...

RNN避坑指南:从数学推导到LSTM/GRU工业级部署实战流程

本文较长&#xff0c;建议点赞收藏&#xff0c;以免遗失。更多AI大模型应用开发学习视频及资料&#xff0c;尽在聚客AI学院。 本文全面剖析RNN核心原理&#xff0c;深入讲解梯度消失/爆炸问题&#xff0c;并通过LSTM/GRU结构实现解决方案&#xff0c;提供时间序列预测和文本生成…...

Redis的发布订阅模式与专业的 MQ(如 Kafka, RabbitMQ)相比,优缺点是什么?适用于哪些场景?

Redis 的发布订阅&#xff08;Pub/Sub&#xff09;模式与专业的 MQ&#xff08;Message Queue&#xff09;如 Kafka、RabbitMQ 进行比较&#xff0c;核心的权衡点在于&#xff1a;简单与速度 vs. 可靠与功能。 下面我们详细展开对比。 Redis Pub/Sub 的核心特点 它是一个发后…...

服务器--宝塔命令

一、宝塔面板安装命令 ⚠️ 必须使用 root 用户 或 sudo 权限执行&#xff01; sudo su - 1. CentOS 系统&#xff1a; yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0.sh && sh install.sh2. Ubuntu / Debian 系统…...