栈和队列OJ练习题及解答

前言

        上一篇博客已经讲到了栈和队列的数据结构,概括一下:栈后进先出(Last In First Out)、队列先进先出(First In First Out)。那么,接下来就来讲讲,关于栈和队列的相关练习题,进一步掌握栈和队列的使用。

一. 用队列实现栈

1. 题目描述

        请你仅使用两个队列实现一个后入先出(LIFO)的栈,并支持普通栈的全部四种操作(pushtoppop 和 empty)。

实现 MyStack 类:

  • void push(int x) 将元素 x 压入栈顶。
  • int pop() 移除并返回栈顶元素。
  • int top() 返回栈顶元素。
  • boolean empty() 如果栈是空的,返回 true ;否则,返回 false 。

注意:

  • 你只能使用队列的标准操作 —— 也就是 push to backpeek/pop from frontsize 和 is empty 这些操作。
  • 你所使用的语言也许不支持队列。 你可以使用 list (列表)或者 deque(双端队列)来模拟一个队列 , 只要是标准的队列操作即可。

示例:

输入:
["MyStack", "push", "push", "top", "pop", "empty"]
[[], [1], [2], [], [], []]
输出:
[null, null, null, 2, 2, false]

解释:
MyStack myStack = new MyStack();
myStack.push(1);
myStack.push(2);
myStack.top(); // 返回 2
myStack.pop(); // 返回 2
myStack.empty(); // 返回 False

提示:

  • 1 <= x <= 9
  • 最多调用100 次 pushpoptop 和 empty
  • 每次调用 pop 和 top 都保证栈不为空

进阶:你能否仅用一个队列来实现栈。

2. 解题思路

        根据上述题目描述,我们需要用两个队列来模拟栈后进先出(Last In First Out),那么问题就在于达到先进后出的效果,怎么如数据和出数据。

        首先队列出数据的话是从队头出,为了达到后出的效果,需要把其他的数据暂时存储起来,这个时候我们的第二个队列的作用就出现了,可以把在其他的数据转移到第二个队列,记录第一个队列头数据,最后清空第一个队列,达到这样的效果。如图1-1所示:

图1-1 双队列模拟栈读取删除数据

        输入的话就将所有数据录入到非空的队列,确保顺序性。

        关于进阶——用一个队列模拟栈:队列里入数据还是一样入,出数据的话就先把队列中前面的数据尾插到原队列,按照这个思路,我们需要知道需要尾插多少次,就在模拟栈的结构里增加一个记录数据总数的整形变量,每次删除数据都尾插数据总数减一次。如图1-2所示:

图1-2 单队列模拟栈出数据

3. 解题代码

        解题代码采用两个队列模拟栈的思路,有兴趣的小伙伴可以尝试单队列模拟。

3.1. 基础代码

        因为需要用队列模拟栈,而C语言不像C++那样能够直接使用库中的队列,所以这里直接提供给大家队列的代码。代码如下:


typedef int QDataType;
// 链式结构:表示队列 
typedef struct QListNode 
{ 
	struct QListNode* _next; 
	QDataType _data; 
}QNode; 

// 队列的结构 
typedef struct Queue 
{ 
	QNode* _front; 
	QNode* _rear; 
}Queue; 

// 初始化队列 
void QueueInit(Queue* q)
{
    assert(q);
    q->_front = q->_rear = NULL;
}

// 检测队列是否为空,如果为空返回非零结果,如果非空返回0 
bool QueueEmpty(Queue* q)
{
    assert(q);

    return q->_front == NULL;
}

// 获取队列中有效元素个数 
int QueueSize(Queue* q)
{
    assert(q);

    if(QueueEmpty(q))
    {
        return 0;
    }
    else
    {
        QNode* cur = q->_front;
        int count = 0;
        while(cur)
        {
            ++count;
            cur = cur->_next;
        }
        return count;
    }
}


// 队尾入队列 
void QueuePush(Queue* q, QDataType data)
{
    assert(q);

    QNode* newnode = (QNode*)malloc(sizeof(QNode));
    if(newnode == NULL)
    {
        perror("QueuePush malloc fail");
        return;
    }

    newnode->_data = data;
    newnode->_next = NULL;

    if(q->_front == NULL)
    {
        q->_front = q->_rear = newnode;
    }
    else
    {
        q->_rear->_next = newnode;
        q->_rear = q->_rear->_next;
    }
}

// 队头出队列 
void QueuePop(Queue* q)
{
    assert(q);
    assert(!QueueEmpty(q));

    if(q->_front == q->_rear)
    {
        free(q->_front);
        q->_front = q->_rear = NULL;
    }
    else
    {
        QNode* next = q->_front->_next;
        free(q->_front);
        q->_front = next;
    }
}

// 获取队列头部元素 
QDataType QueueFront(Queue* q)
{
    assert(q);
    assert(!QueueEmpty(q));

    return q->_front->_data;
}

// 获取队列队尾元素 
QDataType QueueBack(Queue* q)
{
    assert(q);
    assert(!QueueEmpty(q));

    return q->_rear->_data;
}

// 销毁队列 
void QueueDestroy(Queue* q)
{
    assert(q);

    //用cur遍历链表
    QNode* cur = q->_front;
    //遍历
    while(cur)
    {
        //保存下一个位置节点
        QNode* next = cur->_next;
        free(cur);//释放内存
        //移动
        cur = next;
    }
    //队列中指针置为NULL
    q->_front = q->_rear = NULL;
}

3.2. 题目要求的函数实现

3.2.1. 栈的结构

        栈里面包含两个队列,如下所示:

typedef struct {
    Queue q1;
    Queue q2;
} MyStack;
3.2.2. 初始化栈

        为栈的结构开辟空间,并将队列初始化,代码如下:

MyStack* myStackCreate() {
    MyStack* st = (MyStack*)malloc(sizeof(MyStack));
    QueueInit(&(st->q1));
    QueueInit(&(st->q2));
    return st;
}
3.2.3. 销毁栈

        首先释放栈中队列所开辟的空间然后释放栈开辟的空间,代码如下:

void myStackFree(MyStack* obj) {
    QueueDestroy(&(obj->q1));
    QueueDestroy(&(obj->q2));
    free(obj);
}
3.2.4. 判断栈是否为空

        检查两个队列里是否存在数据,都没有栈就为空,这里直接调用队列为空的函数即可,代码如下:

bool myStackEmpty(MyStack* obj) {
    return QueueEmpty(&(obj->q1)) && QueueEmpty(&(obj->q2));
}
3.2.5. 入栈

        向非空的队列入数据,代码如下:

void myStackPush(MyStack* obj, int x) {
    assert(obj);

    //如果队列1不为空,则向队列1中录入数据
    if(!QueueEmpty(&(obj->q1)))
    {
        QueuePush(&(obj->q1), x);
    }
    else//反之就录入数据到队列2
    {
        QueuePush(&(obj->q2), x);
    }
}
3.2.6. 出栈

        根据2.解题思路,代码如下:

int myStackPop(MyStack* obj) {
    assert(obj);

    //假设非空的队列为队列2
    Queue* emp = &(obj->q1);
    Queue* noemp = &(obj->q2);
    //如果队列2为空,就交换队列指针
    if(QueueEmpty(noemp))
    {
        emp = &(obj->q2);
        noemp = &(obj->q1);
    }

    //将非空队列前面的数据储存到另一个队列
    while(QueueSize(noemp) > 1)
    {
        int x = QueueFront(noemp);
        QueuePop(noemp);

        QueuePush(emp, x);
    }
    //记录最后一个队列并输出
    int ret = QueueFront(noemp);
    QueuePop(noemp);
    return ret;
}
3.2.7. 访问栈顶数据

        向非空的队列访问最后储存的数据,代码如下:

int myStackTop(MyStack* obj) {
    assert(obj);

    //如果队列1为空就访问队列1末尾
    if(QueueEmpty(&(obj->q1)))
    {
        return QueueBack(&(obj->q2));
    }
    else//反之访问队列2末尾
    {
        return QueueBack(&(obj->q1));
    }
}

3.3. 运行结果

        判题无误:

图1-3 队列模拟栈题解结果

二. 用栈实现队列

1. 题目描述

        请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作(pushpoppeekempty):

实现 MyQueue 类:

  • void push(int x) 将元素 x 推到队列的末尾
  • int pop() 从队列的开头移除并返回元素
  • int peek() 返回队列开头的元素
  • boolean empty() 如果队列为空,返回 true ;否则,返回 false

说明:

  • 你 只能 使用标准的栈操作 —— 也就是只有 push to toppeek/pop from topsize, 和 is empty 操作是合法的。
  • 你所使用的语言也许不支持栈。你可以使用 list 或者 deque(双端队列)来模拟一个栈,只要是标准的栈操作即可。

示例 1:

输入:
["MyQueue", "push", "push", "peek", "pop", "empty"]
[[], [1], [2], [], [], []]
输出:
[null, null, null, 1, 1, false]

解释:
MyQueue myQueue = new MyQueue();
myQueue.push(1); // queue is: [1]
myQueue.push(2); // queue is: [1, 2] (leftmost is front of the queue)
myQueue.peek(); // return 1
myQueue.pop(); // return 1, queue is [2]
myQueue.empty(); // return false

提示:

  • 1 <= x <= 9
  • 最多调用 100 次 pushpoppeek 和 empty
  • 假设所有操作都是有效的 (例如,一个空的队列不会调用 pop 或者 peek 操作)

进阶:

  • 你能否实现每个操作均摊时间复杂度为 O(1) 的队列?换句话说,执行 n 个操作的总时间复杂度为 O(n) ,即使其中一个操作可能花费较长时间。

2. 解题思路

        用两个栈模拟队列的先进先出(First In First Out),因为栈只能从末尾读取数据,如果要像队列那样保持数据进入的顺序就需要找到队头数据,问题就相当于有两个杯子怎么喝到水杯底部的水。

        所以我们将栈分为入数据的栈和出数据的栈,需要入数据的时候就把出数据的栈的数据放到入数据的栈中然后入数据,反之亦然。如图2-1所示:

图2-1 栈模拟队列1

        这样每次进入数据都需要倒弄栈中的数据时间复杂度为O(N),那么如何降低时间复杂度呢?其实我们不难发现,没必要一直倒弄两个栈中的数据,如果出队列的时候出数据的栈没有数据在将数据倒入出栈栈即可。这样,入队列不需要把出栈的数据倒回去了。如图2-2所示:

图2-2 栈模拟队列2

3. 解题代码

        本题解法直接采用进阶解法。

3.1. 基础代码

        因为需要使用栈的结构,所以这里提供栈的相关代码:

#define INIT 4

// 支持动态增长的栈
typedef int STDataType;
typedef struct Stack
{
	STDataType* _a;
	int _top;		// 栈顶
	int _capacity;  // 容量 
}Stack;

// 初始化栈 
void StackInit(Stack* ps); 
// 入栈 
void StackPush(Stack* ps, STDataType data); 
// 出栈 
void StackPop(Stack* ps); 
// 获取栈顶元素 
STDataType StackTop(Stack* ps); 
// 获取栈中有效元素个数 
int StackSize(Stack* ps); 
// 检测栈是否为空,如果为空返回非零结果,如果不为空返回0 
bool StackEmpty(Stack* ps); 
// 销毁栈 
void StackDestroy(Stack* ps); 

// 初始化栈 
void StackInit(Stack* ps)
{
    assert(ps);
    STDataType* newnode = (STDataType*)malloc(sizeof(STDataType) * INIT);
    if(newnode == NULL)
    {
        perror("StackInit malloc fail");
        exit(1);
    }

    ps->_a = newnode;
    ps->_top = 0;
    ps->_capacity = INIT;
}

// 入栈 
void StackPush(Stack* ps, STDataType data)
{
    assert(ps);
    //容量不足扩容
    if(ps->_top == ps->_capacity)
    {
        STDataType* newnode = (STDataType*)realloc(ps->_a, sizeof(STDataType) * ps->_capacity * 2);
        if(newnode == NULL)
        {
            perror("StackInit malloc fail");
            exit(1);
        }

        ps->_a = newnode;
        ps->_capacity *= 2;
    }
    //入栈
    ps->_a[ps->_top] = data;
    ++ps->_top;
}

// 出栈 
void StackPop(Stack* ps)
{
    assert(ps);

    if(!StackEmpty(ps))
    {
        --ps->_top;
    }
}

// 获取栈顶元素 
STDataType StackTop(Stack* ps)
{
    assert(ps);

    return ps->_a[ps->_top - 1];//栈顶元素在top的上一位
}

// 获取栈中有效元素个数 
int StackSize(Stack* ps)
{
    return ps->_top;
}

// 检测栈是否为空,如果为空返回非零结果,如果不为空返回0 
bool StackEmpty(Stack* ps)
{
    assert(ps);

    return ps->_top == 0;
}

// 销毁栈 
void StackDestroy(Stack* ps)
{
    assert(ps);
    free(ps->_a);
    ps->_a = NULL;
    ps->_capacity = ps->_top = 0;
}

3.2. 题目要求的函数实现

3.2.1. 队列结构
typedef struct {
    Stack st_push;
    Stack st_pop;
} MyQueue;

3.2.2. 队列初始化

MyQueue* myQueueCreate() {
    //开辟队列结构的空间
    MyQueue* qu = (MyQueue*)malloc(sizeof(MyQueue));
    if(qu == NULL)
    {
        perror("malloc fail");
        return NULL;
    }
    //初始化两个栈
    StackInit(&(qu->st_pop));
    StackInit(&(qu->st_push));
    //返回队列空间指针
    return qu;
}
3.2.3. 销毁队列
void myQueueFree(MyQueue* obj) {
    //分别释放栈开辟的空间
    StackDestroy(&(obj->st_pop));
    StackDestroy(&(obj->st_push));
    //释放队列的空间
    free(obj);
}
3.2.4. 队列判空
bool myQueueEmpty(MyQueue* obj) {
    //两个栈都没数据,队列才为空
    return StackEmpty(&(obj->st_pop)) &&  StackEmpty(&(obj->st_push));
}
3.2.5. 队列入数据
void myQueuePush(MyQueue* obj, int x) {
    assert(obj);

    //记录入队列的栈指针,也可以不计,这里方便读者理解简化了
    Stack* _push = &(obj->st_push);
    //将数据录入入栈
    StackPush(_push, x);
}
3.2.6. 队列出数据
int myQueuePop(MyQueue* obj) {
    //记录入队列的栈指针,也可以不计,这里方便读者理解简化了
    Stack* _pop = &(obj->st_pop);
    Stack* _push = &(obj->st_push);

    //如果出数据的栈为空,就将入数据的栈中数据导入到出数据的栈
    if(StackEmpty(_pop))
    {
        while(!StackEmpty(_push))
        {
            int tmp = StackTop(_push);
            StackPop(_push);

            StackPush(_pop, tmp);
        }
    }
    //记录需要出队列的数据,删除并输出
    int ret = StackTop(_pop);
    StackPop(_pop);
    return ret;
}
3.2.7.  队列获取头数据

        直接从出数据的栈中获取栈顶元素,没有元素就将入数据栈中元素导入,代码如下:

int myQueuePeek(MyQueue* obj) {
    Stack* _pop = &(obj->st_pop);
    Stack* _push = &(obj->st_push);
    //如果出数据的栈为空,就将入数据的栈中数据导入到出数据的栈
    if(StackEmpty(_pop))
    {
        while(!StackEmpty(_push))
        {
            int tmp = StackTop(_push);
            StackPop(_push);

            StackPush(_pop, tmp);
        }
    }
    //输出出数据栈头数据
    int ret = StackTop(_pop);
    return ret;
}

3.3. 运行结果

        结果无误:

图2-3 栈模拟队列的结果

三. 设计循环队列

1. 题目描述

        设计你的循环队列实现。 循环队列是一种线性数据结构,其操作表现基于 FIFO(先进先出)原则并且队尾被连接在队首之后以形成一个循环。它也被称为“环形缓冲器”。

        循环队列的一个好处是我们可以利用这个队列之前用过的空间。在一个普通队列里,一旦一个队列满了,我们就不能插入下一个元素,即使在队列前面仍有空间。但是使用循环队列,我们能使用这些空间去存储新的值。

你的实现应该支持如下操作:

  • MyCircularQueue(k): 构造器,设置队列长度为 k 。
  • Front: 从队首获取元素。如果队列为空,返回 -1 。
  • Rear: 获取队尾元素。如果队列为空,返回 -1 。
  • enQueue(value): 向循环队列插入一个元素。如果成功插入则返回真。
  • deQueue(): 从循环队列中删除一个元素。如果成功删除则返回真。
  • isEmpty(): 检查循环队列是否为空。
  • isFull(): 检查循环队列是否已满。

示例:

MyCircularQueue circularQueue = new MyCircularQueue(3); // 设置长度为 3
circularQueue.enQueue(1);  // 返回 true
circularQueue.enQueue(2);  // 返回 true
circularQueue.enQueue(3);  // 返回 true
circularQueue.enQueue(4);  // 返回 false,队列已满
circularQueue.Rear();  // 返回 3
circularQueue.isFull();  // 返回 true
circularQueue.deQueue();  // 返回 true
circularQueue.enQueue(4);  // 返回 true
circularQueue.Rear();  // 返回 4

提示:

  • 所有的值都在 0 至 1000 的范围内;
  • 操作数将在 1 至 1000 的范围内;
  • 请不要使用内置的队列库。

2. 解题思路

2.1. 顺序表模拟

        如果用循序表模拟循环队列,则需要两个指针,指针一指向队列的头,一个指向数组的尾部。入数据从数组尾部进入,队列头用来删除数据,数组开辟的大小为顺序链表的容量。如果循环队列悟空用两个指针指向同一位置来表示,那么想要表示队列为满有两种方式:(1)在队列中增加一个变量记录数组中存在的数据个数。(2)开辟数组大小的时候多开一个空出的空间,那么数组为满的表示为尾指针加一等于头指针。

图3-1 顺序表模拟循环队列

2.2. 链表模拟

        如果用链表模拟就比较麻烦,需要先将链表的空间全部开好,那么剩下的各种操作与顺序表模拟循环队列相同。相比较起来,单向链表模拟如果需要读取队尾数据会比较麻烦,需要将尾指针遍历到尾指针之前的节点,所以使用双向链表模拟会更好,但是那从空间上来说不如顺序表模拟。如果找一个变量记录数据个数,插入的时候按照双向链表尾插,只是限制最后插入的节点个数未必不可行。

3. 解题代码

3.1. 题目要求的函数实现

        根据2.1.的解题思路。

3.1.1. 循环队列的结构
//定义存储数据的类型
typedef int QueueDataType;

typedef struct {
    QueueDataType* a; //顺序表位置
    int pcur;  //头指针
    int ptail; //尾指针
    int size;  //限制的循环队列大小
} MyCircularQueue;
3.1.2. 循环队列初始化

        包括开辟空间,各项指针置为0,记录队列容量,代码如下:

MyCircularQueue* myCircularQueueCreate(int k) {
    MyCircularQueue* cq = (MyCircularQueue*)malloc(sizeof(MyCircularQueue));
    if(cq == NULL)
    {
        perror("malloc fail");
        return NULL;
    }

    cq->a = (QueueDataType*)malloc(sizeof(QueueDataType) * (k + 1));
    cq->pcur = cq->ptail = 0;
    cq->size = k;
    return cq;
}
3.1.3. 判断队列是否为空
bool myCircularQueueIsEmpty(MyCircularQueue* obj) {
    assert(obj);
    return obj->ptail == obj->pcur;
}
3.1.4. 判断队列中数据是否满了

        向这总增加的都需要用总容量取模,防止溢出。

bool myCircularQueueIsFull(MyCircularQueue* obj) {
    assert(obj);
    return (obj->ptail + 1) % (obj->size + 1) == obj->pcur;
}
3.1.5. 向队列中增加数据
bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {
    assert(obj);
    //队列满员了就无法添加
    if(myCircularQueueIsFull(obj))
    {
        return false;
    }
    else
    {
        obj->a[obj->ptail++] = value;
        obj->ptail %= (obj->size + 1);
        return true;
    }
}
3.1.6. 从队列中删除数据
bool myCircularQueueDeQueue(MyCircularQueue* obj) {
    assert(obj);
    //如果队列为空则删除失败
    if(myCircularQueueIsEmpty(obj))
    {
        return false;
    }
    else
    {
        ++obj->pcur;
        obj->pcur %= (obj->size + 1);
        return true;
    }
}
3.1.7. 从队头获取数据
int myCircularQueueFront(MyCircularQueue* obj) {
    assert(obj);
    //队列为空返回-1
    if(myCircularQueueIsEmpty(obj))
    {
        return -1;
    }
    else//反之返回数据
    {
        return obj->a[obj->pcur];
    }
}
3.1.8. 从队尾获取数据
int myCircularQueueRear(MyCircularQueue* obj) {
    assert(obj);
    //为空返回-1
    if(myCircularQueueIsEmpty(obj))
    {
        return -1;
    }
    else//队尾指针-1+k+1最后取模得到后一位的地址
    {
        return obj->a[(obj->ptail + obj->size) % (obj->size + 1)];
    }
}

3.2. 运行结果

        结果无误:

图3-2 

作者结语

        虽然说代码能够解开谜题,但是用文本的方式真的很难把题目短时间说清楚。具体细节还需要读者自己体会,这里最多算是抛了一个砖。

        感谢大家看到这里,那也说明写博客的时间没有白费。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/618612.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

维护祖传项目Tomcat部署war包

文章目录 1. 安装tomcat2. 解决Tomcat启动日志乱码3. idea配置启动war包 1. 安装tomcat 选择免安装版本&#xff0c;只需要在系统变量里面配置一下。 新增系统变量 CATALINA_HOME D:\Users\common\tomcat\apache-tomcat-8.5.97-windows-x64\apache-tomcat-8.5.97 编辑追加Path…

vue3 自定义国际化、elementPlus 国际化

自定义国际化 1. 引入 vue-i18n 插件 pnpm install vue-i18nnext 2. 页面添加语言文件目录&#xff0c;添加自定义的语言文件 3.语言目录里添加 index.ts&#xff0c; 内容如下 import { createI18n } from "vue-i18n";// 自定义语言文件 import zhCN from "…

【Gitlab远程访问本地仓库】Gitlab如何安装配置并结合内网穿透实现远程访问本地仓库进行管理

文章目录 前言1. 下载Gitlab2. 安装Gitlab3. 启动Gitlab4. 安装cpolar5. 创建隧道配置访问地址6. 固定GitLab访问地址6.1 保留二级子域名6.2 配置二级子域名 7. 测试访问二级子域名 前言 GitLab 是一个用于仓库管理系统的开源项目&#xff0c;使用Git作为代码管理工具&#xf…

【Qt-CMake】QT中cmak编译出现CMake Error: The source.. does not match the soused

QT中cmak编译出现CMake Error: The source… does not match the soused 分析 前提是该项目是从另一个路径的项目复制过来的&#xff0c;编写代码时发现无论怎样修改代码&#xff0c;运行后都没有任何变化&#xff0c;以为是qtbug&#xff0c;重构重启都没用&#xff0c;最后…

计算机毕业设计 | vue+springboot线上考试 在线测试系统(附源码)

1&#xff0c;项目介绍 项目背景 在线考试借助于网络来进行&#xff0c;传统考试所必备的考场和监考对于在线考试来说并不是必要项目&#xff0c;因此可以有效减少组织考试做需要的成本以及设施。同时&#xff0c;由于在线考试系统本身具有智能阅卷的功能&#xff0c;也大大减…

RWA会成为下一个风口吗?有哪些值得关注的项目?

随着加密货币市场的迅速发展和成熟&#xff0c;现实世界资产&#xff08;Real World Assets&#xff0c;RWA&#xff09;正逐渐引起人们的关注&#xff0c;并有望成为下一个加密货币领域的风口。本文将探讨RWA的潜力&#xff0c;以及当前值得关注的项目。 RWA的潜力 RWA代表着…

IB 公式解析

公式 3.2. Influence Function 影响函数允许我们在移除样本时估计模型参数的变化&#xff0c;而无需实际移除数据并重新训练模型。 3.3 影响平衡加权因子 3.4 影响平衡损失 3.5 类内重加权 m代表一个批次&#xff08;batch&#xff09;的大小&#xff0c;这意味着公式对一个批…

阮怀俊参与五龙乡黄沙村村企联办“强村公司”

为走好海岛县高质量发展共同富裕特色之路&#xff0c;探索村级集体经济发展新路径、扶持新模式、运行新机制&#xff0c;嵊泗县五龙乡黄沙村股份经济合作社与杭州山舍乡建乡村产业发展有限责任公司联办成“强村公司”。 创始人阮怀俊表示&#xff0c;双方就融合乡域发展和文旅产…

科林Linux_4 信号

#include <signal.h> 信号signal&#xff1a;Linux或Unix系统支持的经典的消息机制&#xff0c;用于处置进程&#xff0c;挂起进程或杀死进程 kill -l #查看系统支持的信号 1~31 Unix经典信号&#xff08;软件开发工程师&#xff09; 32、33信号被系统隐藏&#xf…

虚拟化数据恢复—误还原虚拟机快照怎么办?怎么恢复最新虚拟机数据?

虚拟化技术原理是将硬件虚拟化给不同的虚拟机使用&#xff0c;利用虚拟化技术可以在一台物理机上安装多台虚拟机。误操作或者物理机器出现故障都会导致虚拟机不可用&#xff0c;虚拟机中的数据丢失。 虚拟化数据恢复环境&#xff1a; 有一台虚拟机是由物理机迁移到ESXI上面的&a…

数据库管理-第188期 23ai:怎么用PGQL创建图(20240511)

数据库管理188期 2024-05-10 数据库管理-第188期 23ai:怎么用PGQL创建图&#xff08;20240511&#xff09;1 PGQL创建属性图1.1 PGQL属性图的元数据表1.2 创建一个PGQL属性图1.3 获取PGQL属性图的元数据 2 PGQL属性图3 官方示例演示3.1 插入数据3.2 创建PGQL属性图3.3 通过PGQL…

SpringBoot:SpringBoot原理

SpringBoot高级 SpringBoot配置 配置文件优先级 按照yaml>yml>properties的顺序加载 存在相同配置项,后加载的会覆盖先加载的 加载顺序越靠后,优先级越高 SpringBoot存在其他的多种方式进行配置,如下所示,越靠下优先级越高 1. Default properties (specified by s…

vm虚拟机安装网络适配器驱动卡死/无响应/无限等待状态

大部分原因都是以前的vm没有卸载干净所导致的&#xff0c;只需要使用CCleaner清楚干净就好 使用控制面板里的卸载把VM卸载干净 使用CCleaner软件删除干净注册表&#xff0c;这个软件百度很容易找到&#xff0c;只有十兆左右 打开下载好的软件&#xff0c;不需要注册码&#xff…

长安汽车:基于云器 Lakehouse 的车联网大数据平台建设

近年来随着智能汽车行业的迅速发展&#xff0c;数据也在呈爆炸式增长。长安大数据平台承接了长安在生产上大部分流量应用及日常生产业务应用。本文将分享长安汽车在车联网场景下大数据平台建设面临的一些挑战和具体落地的实践。 主要内容如下&#xff1a; 1. 背景介绍 2. 长…

Java数组:三种初始化

一.静态初始化 代码演示&#xff1a; //静态初始化:创建 赋值int[] a {1,2,3,4,5,6};System.out.println(a[0]); 二.动态初始化 代码演示&#xff1a; //动态初始化:包含默认初始化int[] b new int[10];b[0] 10;System.out.println(b[0]); //10System.out.println(b[1])…

25计算机考研院校数据分析 | 中南大学

中南大学&#xff08;Central South University&#xff09;&#xff0c;位于湖南省长沙市&#xff0c;是中华人民共和国教育部直属的全国重点大学 &#xff0c;中央直管副部级建制&#xff0c;位列国家“双一流”、“985工程”、“211工程”&#xff0c;入选国家“2011计划”牵…

MySQL前缀索引、脏页和干净页、COUNT(*)讨论、表删除内存问题

文章目录 如何加索引如何给身份证号添加索引 SQL语句变慢脏页 (Dirty Pages)干净页 (Clean Pages)为何区分脏页和干净页处理脏页管理策略 flush如何控制 为什么删除表数据后表文件大小不变问题背景核心原因数据存储方式参数影响 解决方案1. 调整innodb_file_per_table设置2. 使…

vs2019 cpp20 规范的线程头文件 <thread> 注释并探讨两个问题

&#xff08;1&#xff09;学习线程&#xff0c;与学习其它容器一样&#xff0c;要多读 STL 库的源码。很多知识就显然而然的明白了。也不用死记硬背一些结论。上面上传了一份注释了一下的 源码。主要是补充泛型推导与函数调用链。基于注释后的源码探讨几个知识点。 STL 库的多…

【SpringBoot】 什么是springboot(三)?springboot使用ajax、springboot使用reids

文章目录 SpringBoot第五章第六章1、springboot使用ajax2、springboot使用reids1、单机版**使用步骤**1-5步67-9步RedisTemplate使用RedisTemplate2、集群版开启集群项目配置1234-5第七章1、springboot文件上传使用步骤1-234-52、springboot邮件发送步骤1-23453、springboot拦截…

【智能算法】最优捕食算法(OFA)原理及实现

目录 1.背景2.算法原理2.1算法思想2.2算法过程 3.结果展示4.参考文献5.代码获取 1.背景 2017年&#xff0c;GY Zhu受到动物行为生态学理论启发&#xff0c;提出了最优捕食算法&#xff08;Optimal Foraging Algorithm, OFA&#xff09;。 2.算法原理 2.1算法思想 OFA灵感来源…