栈和队列(C语言)

栈的定义

栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶,另一端称为栈底。栈中的数据元素遵守后进先出LIFO(Last In First Out)的原则。
压栈:栈的插入操作叫做进栈/压栈/入栈,入数据在栈顶。
出栈:栈的删除操作叫做出栈。出数据也在栈顶
可以把他想象成一个水杯

栈代码的实现

结构的定义,以及函数声明

#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <stdbool.h>typedef int QueueNodeType;
struct QueueNode {struct QueueNode* next;QueueNodeType data;
}typedef QueueNode;//队列只需要在队尾插入,队头删除,不需要改变里面的内容
//所以只需要改变头尾
struct Queue {struct QueueNode* head;struct QueueNode* tail;size_t _size;
}typedef Queue;// 初始化队列
void QueueInit(Queue* q);
// 队尾入队列
void QueuePush(Queue* q, QueueNodeType data);
// 队头出队列
void QueuePop(Queue* q);
// 获取队列头部元素
QueueNodeType QueueFront(Queue* q);
// 获取队列队尾元素
QueueNodeType QueueBack(Queue* q);
// 获取队列中有效元素个数
size_t QueueSize(Queue* q);
// 检测队列是否为空,如果为空返回非零结果,如果非空返回0 
bool QueueEmpty(Queue* q);
// 销毁队列
void QueueDestroy(Queue* q);

接口的实现

#define  _CRT_SECURE_NO_WARNINGS 1
#include "queue.h"void QueueInit(Queue* q)
{assert(q);q->head = NULL;q->tail = NULL;q->_size = 0;
}void QueueDestroy(Queue* q)
{assert(q);while (q->head){QueueNode* next = q->head->next;free(q->head);q->head = next;}q->tail = NULL;q->_size = 0;
}void QueuePush(Queue* q, QueueNodeType data)
{assert(q);QueueNode* newnode = (QueueNode*)malloc(sizeof(QueueNode));assert(newnode);newnode->data = data;newnode->next = NULL;//尾插if (q->tail == NULL){q->tail = q->head = newnode;}else{q->tail->next = newnode;q->tail = q->tail->next;}q->_size++;
}void QueuePop(Queue* q)
{assert(q);assert(!QueueEmpty(q));QueueNode* newhead = q->head->next;free(q->head);q->head = newhead;if (q->head == NULL){q->tail = NULL;}q->_size--;
}bool QueueEmpty(Queue* q)
{assert(q);return q->head == NULL;
}QueueNodeType QueueFront(Queue* q)
{assert(q);assert(!QueueEmpty(q));return q->head->data;
}QueueNodeType QueueBack(Queue* q)
{assert(q);assert(!QueueEmpty(q));return q->tail->data;
}size_t QueueSize(Queue* q)
{assert(q);return q->_size;
}

队列的定义

队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出FIFO(First In First Out)
入队列:进行插入操作的一端称为队尾
出队列:进行删除操作的一端称为队头

队列代码的实现

结构的定义,以及函数声明

#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <stdbool.h>typedef int QueueNodeType;
struct QueueNode {struct QueueNode* next;QueueNodeType data;
}typedef QueueNode;//队列只需要在队尾插入,队头删除,不需要改变里面的内容
//所以只需要改变头尾
struct Queue {struct QueueNode* head;struct QueueNode* tail;size_t _size;
}typedef Queue;// 初始化队列
void QueueInit(Queue* q);
// 队尾入队列
void QueuePush(Queue* q, QueueNodeType data);
// 队头出队列
void QueuePop(Queue* q);
// 获取队列头部元素
QueueNodeType QueueFront(Queue* q);
// 获取队列队尾元素
QueueNodeType QueueBack(Queue* q);
// 获取队列中有效元素个数
size_t QueueSize(Queue* q);
// 检测队列是否为空,如果为空返回非零结果,如果非空返回0 
bool QueueEmpty(Queue* q);
// 销毁队列
void QueueDestroy(Queue* q);

接口的实现

#define  _CRT_SECURE_NO_WARNINGS 1
#include "queue.h"void QueueInit(Queue* q)
{assert(q);q->head = NULL;q->tail = NULL;q->_size = 0;
}void QueueDestroy(Queue* q)
{assert(q);while (q->head){QueueNode* next = q->head->next;free(q->head);q->head = next;}q->tail = NULL;q->_size = 0;
}void QueuePush(Queue* q, QueueNodeType data)
{assert(q);QueueNode* newnode = (QueueNode*)malloc(sizeof(QueueNode));assert(newnode);newnode->data = data;newnode->next = NULL;//尾插if (q->tail == NULL){q->tail = q->head = newnode;}else{q->tail->next = newnode;q->tail = q->tail->next;}q->_size++;
}void QueuePop(Queue* q)
{assert(q);assert(!QueueEmpty(q));QueueNode* newhead = q->head->next;free(q->head);q->head = newhead;if (q->head == NULL){q->tail = NULL;}q->_size--;
}bool QueueEmpty(Queue* q)
{assert(q);return q->head == NULL;
}QueueNodeType QueueFront(Queue* q)
{assert(q);assert(!QueueEmpty(q));return q->head->data;
}QueueNodeType QueueBack(Queue* q)
{assert(q);assert(!QueueEmpty(q));return q->tail->data;
}size_t QueueSize(Queue* q)
{assert(q);return q->_size;
}

题目1:括号匹配问题

题目链接:https://leetcode.cn/problems/valid-parentheses/description/
在这里插入图片描述
思路详解:
在这里插入图片描述

参考代码

typedef char StackType;struct Stack {StackType* _a;int _top;int _capacity;
}typedef Stack;//初始化栈
void StackInit(Stack* pStack);//入栈
void StackPush(Stack* pStack,StackType data);//出栈
void StackPop(Stack* pStack);//获取栈顶元素
StackType StackTop(const Stack* pStack);//获取栈中有效元素个数
int StackSize(const Stack* pStack);//判断栈是否为空
bool StackEmpty(Stack* pStack);//销毁栈
void StackDestroy(Stack* pStack);void StackInit(Stack* pStack)
{pStack->_a = NULL;pStack->_capacity = 0;pStack->_top = 0;
}void StackPush(Stack* pStack,StackType data)
{assert(pStack);if (pStack->_top == pStack->_capacity){int newCapacity = pStack->_capacity == 0 ? 4 : pStack->_capacity * 2;StackType* newa = NULL;newa = (StackType*)realloc(pStack->_a, sizeof(StackType) * newCapacity);if (newa == NULL){perror("StackPush():: realloc::");return;}pStack->_a = newa;pStack->_capacity = newCapacity;}pStack->_a[pStack->_top] = data;pStack->_top++;
}void StackPop(Stack* pStack)
{assert(pStack);assert(!StackEmpty(pStack));pStack->_top--;
}StackType StackTop(const Stack* pStack)
{// 因为top的初始值为0 ,而插入一个数据后为1,// 但是所对应的数组下标为0assert(pStack);assert(!StackEmpty(pStack));return pStack->_a[pStack->_top - 1];
}int StackSize(const Stack* pStack)
{return pStack->_top;
}bool StackEmpty(Stack* pStack)
{assert(pStack);return pStack->_top == 0;
}void StackDestroy(Stack* pStack)
{free(pStack->_a);pStack->_capacity = 0;pStack->_top = 0;pStack->_a = NULL;
}
//这里题目实现,上面都是栈的实现和接口,因为是C语言的关系没有STL库所以要自己造轮子
bool isValid(char* s) 
{Stack stack = { 0 };StackInit(&stack);while (*s){if (*s == '(' || *s == '{' || *s == '['){StackPush(&stack, *s);s++;}else{//第一个字符为有括号,证明不是有效括号,直接返回NULLif(StackEmpty(&stack)){//特殊案例如果是 [[]]],这里如果直接返回的话就会导致内存泄露StackDestroy(&stack);return false;}StackType top = StackTop(&stack);StackPop(&stack);if (top == '(' && *s != ')'|| top == '{' && *s != '}'|| top == '[' && *s != ']'){StackDestroy(&stack);return false;}else{ s++;}}}bool ret = StackEmpty(&stack);StackDestroy(&stack);return ret;// return true;
}

题目2:用队列实现栈

题目链接:https://leetcode.cn/problems/implement-stack-using-queues/
在这里插入图片描述
思路详解:
在这里插入图片描述
在这里插入图片描述

参考代码:

typedef int QueueNodeType;
struct QueueNode {struct QueueNode* next;QueueNodeType data;
}typedef QueueNode;//队列只需要在队尾插入,队头删除,不需要改变里面的内容
//所以只需要改变头尾
struct Queue {struct QueueNode* head;struct QueueNode* tail;size_t _size;
}typedef Queue;// 初始化队列
void QueueInit(Queue* q);
// 队尾入队列
void QueuePush(Queue* q, QueueNodeType data);
// 队头出队列
void QueuePop(Queue* q);
// 获取队列头部元素
QueueNodeType QueueFront(Queue* q);
// 获取队列队尾元素
QueueNodeType QueueBack(Queue* q);
// 获取队列中有效元素个数
size_t QueueSize(Queue* q);
// 检测队列是否为空,如果为空返回非零结果,如果非空返回0 
bool QueueEmpty(Queue* q);
// 销毁队列
void QueueDestroy(Queue* q);void QueueInit(Queue* q)
{assert(q);q->head = NULL;q->tail = NULL;q->_size = 0;
}void QueueDestroy(Queue* q)
{assert(q);while (q->head){QueueNode* next = q->head->next;free(q->head);q->head = next;}q->tail = NULL;q->_size = 0;
}void QueuePush(Queue* q, QueueNodeType data)
{assert(q);QueueNode* newnode = (QueueNode*)malloc(sizeof(QueueNode));assert(newnode);newnode->data = data;newnode->next = NULL;//尾插if (q->tail == NULL){q->tail = q->head = newnode;}else{q->tail->next = newnode;q->tail = q->tail->next;}q->_size++;
}void QueuePop(Queue* q)
{assert(q);assert(!QueueEmpty(q));QueueNode* newhead = q->head->next;free(q->head);q->head = newhead;if (q->head == NULL){q->tail = NULL;}q->_size--;
}bool QueueEmpty(Queue* q)
{assert(q);return q->head == NULL;
}QueueNodeType QueueFront(Queue* q)
{assert(q);assert(!QueueEmpty(q));return q->head->data;
}QueueNodeType QueueBack(Queue* q)
{assert(q);assert(!QueueEmpty(q));return q->tail->data;
}size_t QueueSize(Queue* q)
{assert(q);return q->_size;
}//上面是队列的接口,从这里下面才开始对栈的实现
typedef struct {Queue q1;Queue q2;
} MyStack;MyStack* myStackCreate() {MyStack* mystack = (MyStack*)malloc(sizeof(MyStack));QueueInit(&mystack->q1);QueueInit(&mystack->q2);return mystack;
}void myStackPush(MyStack* obj, int x) {if(QueueEmpty(&obj->q1)){QueuePush(&obj->q2,x);}else{QueuePush(&obj->q1,x);}
}int myStackPop(MyStack* obj) {//找那个是为空队列Queue* emptyQueue = &obj->q1;Queue* nonEmptyQueue = &obj->q2;if(QueueEmpty(&obj->q2)){emptyQueue = &obj->q2;nonEmptyQueue = &obj->q1;}//保留非空队列中的最后一个元素,其余元素转移到空队列里面while(QueueSize(nonEmptyQueue) > 1){QueuePush(emptyQueue,QueueFront(nonEmptyQueue));QueuePop(nonEmptyQueue);}int ret = QueueFront(nonEmptyQueue);QueuePop(nonEmptyQueue);return ret;
}int myStackTop(MyStack* obj) {//两个队列中,非空的那个队列的队尾就是栈顶if(QueueEmpty(&obj->q1)){return QueueBack(&obj->q2); }else{return QueueBack(&obj->q1);}
}bool myStackEmpty(MyStack* obj) {return QueueEmpty(&obj->q1) && QueueEmpty(&obj->q2);
}void myStackFree(MyStack* obj) {QueueDestroy(&obj->q1);QueueDestroy(&obj->q2);free(obj);
}

题目3:用栈实现队列

题目链接:https://leetcode.cn/problems/implement-queue-using-stacks/description/

在这里插入图片描述
思路详解:
在这里插入图片描述

参考代码:

typedef char StackType;struct Stack {StackType* _a;int _top;int _capacity;
}typedef Stack;//初始化栈
void StackInit(Stack* pStack);//入栈
void StackPush(Stack* pStack,StackType data);//出栈
void StackPop(Stack* pStack);//获取栈顶元素
StackType StackTop(Stack* pStack);//获取栈底元素
StackType StackBottom(Stack* pStack);//获取栈中有效元素个数
int StackSize(Stack* pStack);//判断栈是否为空
bool StackEmpty(Stack* pStack);//销毁栈
void StackDestroy(Stack* pStack);void StackInit(Stack* pStack)
{pStack->_a = NULL;pStack->_capacity = 0;pStack->_top = 0;
}void StackPush(Stack* pStack,StackType data)
{assert(pStack);if (pStack->_top == pStack->_capacity){int newCapacity = pStack->_capacity == 0 ? 4 : pStack->_capacity * 2;StackType* newa = NULL;newa = (StackType*)realloc(pStack->_a, sizeof(StackType) * newCapacity);if (newa == NULL){perror("StackPush():: realloc::");return;}pStack->_a = newa;pStack->_capacity = newCapacity;}pStack->_a[pStack->_top] = data;pStack->_top++;
}void StackPop(Stack* pStack)
{assert(pStack);assert(!StackEmpty(pStack));pStack->_top--;
}StackType StackTop(Stack* pStack)
{assert(pStack);assert(!StackEmpty(pStack));// 因为top的初始值为0 ,而插入一个数据后为1,// 但是所对应的数组下标为0return pStack->_a[pStack->_top - 1];
}StackType StackBottom(Stack* pStack)
{assert(pStack);assert(!StackEmpty(pStack));return pStack->_a[0];
}int StackSize(Stack* pStack)
{return pStack->_top;
}bool StackEmpty(Stack* pStack)
{assert(pStack);return pStack->_top == 0;
}void StackDestroy(Stack* pStack)
{free(pStack->_a);pStack->_capacity = 0;pStack->_top = 0;pStack->_a = NULL;
}//这里开始才是实现队列的代码
typedef struct {Stack PushStack;Stack PopStack;
} MyQueue;MyQueue* myQueueCreate() {MyQueue* queue= (MyQueue*)malloc(sizeof(MyQueue));StackInit(&queue->PushStack);StackInit(&queue->PopStack);return queue;
}void myQueuePush(MyQueue* obj, int x) {StackPush(&obj->PushStack,x);
}int myQueuePop(MyQueue* obj) {if(StackEmpty(&obj->PopStack)){while(!StackEmpty(&obj->PushStack)){StackPush(&obj->PopStack,StackTop(&obj->PushStack));StackPop(&obj->PushStack);}}int popTop = StackTop(&obj->PopStack);StackPop(&obj->PopStack);return popTop;
}//返回队头
int myQueuePeek(MyQueue* obj) {if(StackEmpty(&obj->PopStack)){while(!StackEmpty(&obj->PushStack)){StackPush(&obj->PopStack,StackTop(&obj->PushStack));StackPop(&obj->PushStack);}}return StackTop(&obj->PopStack);
}bool myQueueEmpty(MyQueue* obj) {return StackEmpty(&obj->PushStack) && StackEmpty(&obj->PopStack);
}void myQueueFree(MyQueue* obj) {StackDestroy(&obj->PopStack);StackDestroy(&obj->PushStack);free(obj);
}

题目4:设计循环队列

题目链接:https://leetcode.cn/problems/design-circular-queue/description/
在这里插入图片描述
思路详解:

在这里插入图片描述

参考代码:
用数组实现:

typedef struct {int* _a; //数组int _head; //头下标int _tail; //尾下标int _k; //存储的元素个数
} MyCircularQueue;
bool myCircularQueueIsEmpty(MyCircularQueue* obj);
bool myCircularQueueIsFull(MyCircularQueue* obj);// 初始化
MyCircularQueue* myCircularQueueCreate(int k) {MyCircularQueue* cq = (MyCircularQueue*)malloc(sizeof(MyCircularQueue));assert(cq);cq->_a = (int*)malloc(sizeof(int) * (k + 1));assert(cq->_a);cq->_head = 0;cq->_tail = 0;cq->_k = k;return cq;
}// 入队列
bool myCircularQueueEnQueue(MyCircularQueue * obj, int value) {assert(obj);if (myCircularQueueIsFull(obj)){return false;}else{obj->_a[obj->_tail] = value;if (obj->_tail >= obj->_k){obj->_tail = 0;}else{obj->_tail++;}return true;}
}//删队列
bool myCircularQueueDeQueue(MyCircularQueue* obj) {assert(obj);if (myCircularQueueIsEmpty(obj)){return false;}if (obj->_head >= obj->_k){obj->_head = 0;return true;}else{obj->_head++;return true;}
}//队头
int myCircularQueueFront(MyCircularQueue* obj) {assert(obj);if (myCircularQueueIsEmpty(obj)){return -1; }return obj->_a[obj->_head];
}//队尾
int myCircularQueueRear(MyCircularQueue* obj) {assert(obj);if (myCircularQueueIsEmpty(obj)){return -1;}//方法1;if (obj->_tail == 0){return obj->_a[obj->_k];}else{return obj->_a[obj->_tail - 1];}//方法2:/*int i = (obj->_tail + obj->_k) % (obj->_k + 1);return obj->_a[i];*/
}//判空
bool myCircularQueueIsEmpty(MyCircularQueue* obj) {assert(obj);return obj->_head == obj->_tail;
}//判满
bool myCircularQueueIsFull(MyCircularQueue* obj) {assert(obj);return (obj->_tail + 1) % (obj->_k + 1) == obj->_head;
}//销毁
void myCircularQueueFree(MyCircularQueue* obj) {assert(obj);free(obj->_a);free(obj);
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Elasticsearch:Golang ECS 日志记录 - zerolog

ECS 记录器是你最喜欢的日志库的格式化程序/编码器插件。它们可让你轻松地将日志格式化为与 ECS 兼容的 JSON。在本教程中&#xff0c;我将详述如何 编码器以 JSON 格式记录日志&#xff0c;并以 ECS 错误格式处理错误字段的记录。 默认情况下&#xff0c;会添加以下字段&…

【算法】深入理解并优化算法:提升软件开发效率与质量

目录 一、算法的基本概念 输入 输出 确定性 有限性 有效性 二、常见算法类型 1. 排序算法 选择排序&#xff08;Selection Sort&#xff09; 插入排序&#xff08;Insertion Sort&#xff09; 快速排序&#xff08;Quick Sort&#xff09; 归并排序&#xff08;Mer…

Langchain核心模块与实战[7]:专业级Prompt工程调教LLM[输入输出接口、提示词模板与例子选择器的协同工程]

Langchain核心模块与实战[7]:专业级Prompt工程调教LLM[输入输出接口、提示词模板与例子选择器的协同工程] 1. 大模型IO接口 任何语言模型应用的核心元素是…模型的输入和输出。LangChain提供了与任何语言模型进行接口交互的基本组件。 提示 prompts : 将模型输入模板化、动态…

云原生周刊:Kubernetes v1.31 中的移除和主要变更|2024.7.22

开源项目 Argo Rollouts Argo Rollouts 是一个 Kubernetes 控制器和一组自定义资源定义&#xff08;CRDs&#xff09;&#xff0c;提供高级部署功能&#xff0c;例如蓝绿部署、金丝雀部署、金丝雀分析、实验以及渐进式交付功能给 Kubernetes。 Argo Rollouts 可选地集成了 I…

MATLAB--文件操作相关指令

文章目录 文件操作相关指令前言 M文件创建MATLAB文件操作指令MATLAB文件流控制 文件操作相关指令 前言 记录一下M文件创建、操作、获取信息等相关资料。   MATLAB的M文件是用来代替MATLAB命令行窗口输入指令的文件。因此所有的MATLAB指令都可以再MATLAB的M文件中调用. M文件…

python 读取excel 并处理被合并单元格的数据

业务需求是 读取excel数据 并按指定规则拼接数据保存到 md文件中 遇到的问题&#xff0c;大量空列和空行 造成读取数据卡住&#xff0c;或者逐行 逐单元格遍历 过慢。&#xff08;例如&#xff1a;实际可用数据 一千 行&#xff0c;ws.max_row 读取到的有效行是十万 &#xff…

Harmony学习(二)------ArkUI(2)

1.主轴对齐方式.justifyContent build() {Column(){Text().width(200).height(100).backgroundColor(Color.Yellow).border({width:2})Text().width(200).height(100).backgroundColor(Color.Yellow).border({width:2}).margin(10)Text().width(200).height(100).backgroundCol…

关于iphone不能下载三方软件

iPhone 不能下载第三方软件的原因主要是因为苹果公司严格控制其应用生态系统&#xff0c;确保所有应用都通过其官方的 App Store 分发。这有几个主要原因&#xff1a; 安全性&#xff1a;苹果公司希望通过这种方式减少恶意软件的传播&#xff0c;保护用户的隐私和数据安全。所…

I can‘t link the chatbot model with react

题意&#xff1a;我无法将聊天机器人模型 chatbot 与React连接起来 问题背景&#xff1a; This is the model from flask import Flask, request, jsonify from flask_cors import CORS import json import nltk import numpy as np import random import pickle from time i…

【javascript】关于js控制滚动的一些注意事项

滚动方式有2种 1、element.scrollIntoView // 假设你有一个元素的ID是element-id const element document.getElementById(element-id); // 滚动到该元素 element.scrollIntoView(); // 如果你想要平滑滚动&#xff0c;可以传递一个选项对象 element.scrollIntoView({ behav…

Windows图形界面(GUI)-MFC-C/C++ - 键鼠操作

公开视频 -> 链接点击跳转公开课程博客首页 -> ​​​链接点击跳转博客主页 目录 MFC鼠标 派发流程 鼠标消息(客户区) 鼠标消息(非客户) 坐标处理 客户区 非客户 坐标转换 示例代码 MFC键盘 击键消息 虚拟键代码 键状态 MFC鼠标 派发流程 消息捕获&#…

科研绘图系列:R语言热图(heatmap)

介绍 热图是一种数据可视化技术,通常用于展示数据的分布情况。它通过颜色的变化来表示数据的大小或密度,使得观察者能够直观地理解数据集中的模式和趋势。以下是热图的一些关键特点和应用场景: 数据分布:热图可以显示数据在不同区域的分布情况,比如在地图上显示不同地区的…

【cocos creator】ts中export的模块管理

在 TypeScript&#xff08;TS&#xff09;中&#xff0c;export 和 import 的概念与 Java 中的 public 类、接口以及 import 语句有一些相似之处。可以用以下方式来类比理解&#xff1a; Export 在 TypeScript 中&#xff0c;export 用于将模块中的变量、函数、类等暴露给外部…

WHAT - CSS :root 变量定义和使用(var)

在日常开发中&#xff0c;我们经常遇到如下 CSS 代码&#xff1a; bg-primary {background-color: var(--primary-color); } disabled-foreground {color: var(--disabled-foreground-color); }这些变量通常来自于CSS变量&#xff08;也称为CSS自定义属性&#xff09;&#xf…

Mac 下华为鸿蒙 :DevEco Studio 开发工具下载

1.登录&#xff1a;华为开发者中心--开发--下载工具DevEco Studio 2.下载完成后 &#xff0c;安装&#xff0c;并创建一个新项目。 3.Tools --点击SDK Manager 下载SDK: 如果报&#xff1a;淘宝镜像源错误&#xff1a; npm ERR! code CERT_HAS_EXPIRED npm ERR! errno CERT_H…

Spring 的BeanPostProcessor 有什么作用?内置那些BeanPostProcessor

在 Spring 框架中&#xff0c;BeanPostProcessor 是一个用于在容器初始化时对 bean 的创建过程进行扩展和自定义的接口。它的作用主要体现在以下几个方面&#xff1a; BeanPostProcessor 的作用 前置处理 (postProcessBeforeInitialization)&#xff1a; 在调用 bean 的初始化…

使用docker-compose给自己上传的JAR打包成镜像并自动启动容器每次更新jar包自动化执行脚本

在持续集成和部署&#xff08;CI/CD&#xff09;过程中&#xff0c;自动化是提高效率的关键。本文将介绍如何使用Docker Compose将一个上传的JAR文件打包成Docker镜像&#xff0c;并在容器中自动启动该应用程序。同时&#xff0c;创建一个脚本&#xff0c;以便在每次更新JAR包后…

js动态规划

动态规划&#xff08;英语&#xff1a;Dynamic programming&#xff0c;简称 DP&#xff09;是一种在数学、管理科学、计算机科学、经济学和生物信息学中使用的&#xff0c;把原问题分解为相对简单的子问题 动态规划常常适用于有重叠子问题和最优子结构性质的问题&#xff0c;…

优略解距离法—Topsis模型【清风数模学习笔记】

层次分析法的局限性 &#xff08;1&#xff09;决策层不能太多 &#xff08;2&#xff09;数据已知&#xff0c;使用层次分析法不准确 构造计算评分 相较于取卷面理论上的最高分&#xff08;100&#xff09;和最低分&#xff08;0&#xff09;&#xff0c;取分数区间上的最…

Qt编程技巧总结篇(6)-QCustomPlot绘图篇(一)

文章目录 Qt编程技巧总结篇(6)-QCustomPlot绘图篇(一)图轴的放缩、拖拽与粗体图画标题设计轴标题设计图例设计简单画线的步骤1小结Qt编程技巧总结篇(6)-QCustomPlot绘图篇(一) 多线程学习,告一段落,这里开始使用QCustomPlot进行绘图操作,原来已经有一篇《Qt编程技巧…