探索数据结构:特殊的双向队列

✨✨ 欢迎大家来到贝蒂大讲堂✨✨

🎈🎈养成好习惯,先赞后看哦~🎈🎈

所属专栏:数据结构与算法
贝蒂的主页:Betty’s blog

1. 双向队列的定义

**双向队列(double‑ended queue)**是一种特殊的队列,它允许在队列的队尾与队头插入与删除元素。根据其定义,我们也可以理解为两个栈在栈底相连。

  1. 队尾入队

img

  1. 队首入队

img

  1. 队尾出队

img

  1. 队尾出队

img

2. 双向队列的分类

双向队列也是线性表的一种,所以也可以分别用链表数组实现。基于链表实现:为了方便双向队列在尾部的插入与删除操作,所以我们选用双向链表。基于数组实现:与队列实现类似,需要用循环数组(原因参考队列实现)。

img

3. 双向队列的功能

  1. 队列的初始化。
  2. 判断队列是否为空。。
  3. 返回队头与队尾的元素。
  4. 返回队列的大小。
  5. 入队与出队。
  6. 打印队列的元素。
  7. 销毁队列。

4. 双向队列的声明

4.1. 链式队

双向队列与普通队列的声明区别就在于双向队列是基于双向链表的方式实现。

typedef int QDataType;
typedef struct DuListNode
{
	QDataType data;
	struct Node* prev;
	struct Node* next;
}DuListNode;

typedef struct Deque
{
	size_t size;
	DuListNode* front;
	DuListNode* rear;
}Deque;

4.2. 循环队

循环队列的实现方式与普通队列差不多。

typedef int QDataType;
#define MAXSIZE 50  //定义元素的最大个数
typedef struct {
    QDataType *data;
    int front;  //头指针
    int rear;   //尾指针
}Deque;

5. 队列的初始化

5.1. 链式队

void DequeInit(Deque* d)//初始化
{
	assert(d);
	d->front = NULL;
	d->rear = NULL;
	d->size = 0;
}

5.2. 循环队

void DequeInit(Deque* d)//初始化
{
	d->data = (QDataType*)malloc(sizeof(QDataType )* MAXSIZE);
	if (d->data == NULL)
	{
		perror("malloc fail:");
		return;
	}
	d->front = 0;
	d->rear = 0;
}

5.3. 复杂度分析

  • 时间复杂度:无论是链式队还是循环队列花费时间都是一个常数,所以时间复杂度为O(1)。
  • 空间复杂度:链式队空间是一个固定大小,空间复杂度为O(1)。而需要开辟整个队列的大小,空间复杂度为O(N)。

6. 判断队列是否为空

6.1. 链式队

bool DequeEmpty(Deque* d)//判断是否为空
{
	assert(d);
	return (d->front == NULL) && (d->rear == NULL);
}

6.2. 循环队

bool DequeEmpty(Deque* d)//判断是否为空
{
	assert(d);
	return d->front == d->rear;
}

6.3. 复杂度分析

  • 时间复杂度:无论是链式队还是循环队列花费时间都是一个常数,所以时间复杂度为O(1)。
  • 空间复杂度:无论是链式队还是循环队列花费空间都是一个固定大小,所以空间复杂度为O(1)。

7. 判断队列是否为满

7.1. 链式队

链式队并不需要判断。

7.2. 循环队

为什么要取模操作,可以参考一下上一篇普通队列的实现,同下。

bool DequeFull(Deque* d)//判断队列是否满
{
	assert(d);
	return (d->rear + 1) % MAXSIZE == d->front;
}

8. 返回队头与队尾的元素

8.1. 链式队

QDataType DequeFront(Deque* d)//获取队头元素
{
	assert(d);
	assert(!DequeEmpty(d));
	return d->front->data;
}
QDataType DequeBack(Deque* d)//获取队尾元素
{
	assert(d);
	assert(!DequeEmpty(d));
	return d->rear->data;
}

8.2. 循环队

QDataType DequeFront(Deque* d)//获取队头元素
{
	assert(d);
	assert(!DequeEmpty(d));
	return d->data[d->front];
}
QDataType DequeBack(Deque* d)//获取队尾元素
{
	assert(d);
	assert(!DequeEmpty(d));
	return d->data[(d->rear-1+MAXSIZE)%MAXSIZE];
}

8.3. 复杂度分析

  • 时间复杂度:无论是链式队还是循环队列花费时间都是一个常数,所以时间复杂度为O(1)。
  • 空间复杂度:无论是链式队还是循环队列花费空间都是一个固定大小,所以空间复杂度为O(1)

9. 返回队列的大小

9.1. 链式队

size_t DequeSize(Deque* d)//队列长度
{
	return d->size;
}

9.2. 循环队

size_t DequeSize(Deque* d)//获取队列长度
{
	assert(d);
	return (d->rear - d->front + MAXSIZE) % MAXSIZE;
}

9.3. 复杂度分析

  • 时间复杂度:无论是链式队还是循环队列花费时间都是一个常数,所以时间复杂度为O(1)。
  • 空间复杂度:无论是链式队还是循环队列花费空间都是一个固定大小,所以空间复杂度为O(1)

10. 入队

10.1. 链式队

10.1.1. 队头入队
void DequeFrontPush(Deque* d, QDataType x)//队首入队
{
	assert(d);
	DuListNode* newnode = (DuListNode*)malloc(sizeof(DuListNode));
	if (newnode == NULL)
	{
		perror("malloc fail");
		return;
	}
	newnode->data = x;
	newnode->next = NULL;
	newnode->prev = NULL;
	if (d->front == NULL)
	{
		d->front = d->rear = newnode;
	}
	else
	{
		d->front->prev = newnode;
		newnode->next = d->front;
		d->front = newnode;
	}
    d->size++;
}
10.1.2. 队尾入队
void DequeRearPush(Deque* d, QDataType x)//队尾入队
{
	assert(d);
	DuListNode* newnode = (DuListNode*)malloc(sizeof(DuListNode));
	if (newnode == NULL)
	{
		perror("malloc fail");
		return;
	}
	newnode->data = x;
	newnode->next = NULL;
	newnode->prev = NULL;
	if (d->front == NULL)
	{
		d->front = d->rear = newnode;
	}
	else
	{
		d->rear->next = newnode;
		newnode->prev = d->rear;
		d->rear = newnode;
	}
	d->size++;
}

10.2. 循环队

入队需要提前判断队列是否为满。

10.2.1. 队头入队
void DequeFrontPush(Deque* d, QDataType x)//队首入队
{
	assert(d);
	if (DequeFull(d))
	{
		printf("队列已满\n");
		return;
	}
	d->data[(d->front - 1 + MAXSIZE) % MAXSIZE]=x;
	d->front = (d->front - 1 + MAXSIZE) % MAXSIZE;
}
10.2.2. 队尾入队
void DequeRearPush(Deque* d, QDataType x)//队尾入队
{
	assert(d);
	if (DequeFull(d))
	{
		printf("队列已满\n");
		return;
	}
	d->data[d->rear] = x;
	d->rear = (d->rear + 1) % MAXSIZE;
}

10.3. 复杂度分析

  • 时间复杂度:无论是链式队还是循环队列花费时间都是一个常数,所以时间复杂度为O(1)。
  • 空间复杂度:无论是链式队还是循环队列花费空间都是一个固定大小,所以空间复杂度为O(1)

11. 出队

11.1. 链式队

出队需要提前判断队列是否为空。

11.1.1. 队头出队
void DequeFrontPop(Deque* d)//队首出队
{
	assert(d);
	assert(!DequeEmpty(d));
	//1.只有一个结点
	if (d->front == d->rear)
	{
		free(d->front);
		d->front = d->rear = NULL;
	}
	//2.有多个结点
	else
	{
		DuListNode* next = d->front->next;
		next->prev = NULL;
		d->front->next = NULL;
		free(d->front);
		d->front = next;
	}
	d->size--;
}
11.1.2. 队尾出队
void DequeRearPop(Deque* d)//队尾出队
{
	assert(d);
	assert(!DequeEmpty(d));
	//1.只有一个结点
	if (d->front == d->rear)
	{
		free(d->front);
		d->front = d->rear = NULL;
	}
	else
	{
		DuListNode* prev = d->rear->prev;
		prev->next = NULL;
		d->rear->prev = NULL;
		free(d->rear);
		d->rear = prev;
	}
    d->size--;
}

11.2. 循环队

11.2.1. 队头出队
void DequeFrontPop(Deque* d)//队首出队
{
	assert(d);
	assert(!DequeEmpty(d));
	d->front = (d->front + 1) % MAXSIZE;
}
11.2.2. 队尾出队
void DequeRearPop(Deque* d)//队尾出队
{
	assert(d);
	assert(!DequeEmpty(d));
	d->rear = (d->rear - 1+MAXSIZE) % MAXSIZE;
}

11.3. 复杂度分析

  • 时间复杂度:无论是链式队还是循环队列花费时间都是一个常数,所以时间复杂度为O(1)。
  • 空间复杂度:无论是链式队还是循环队列花费空间都是一个固定大小,所以空间复杂度为O(1)

12. 打印队列元素

12.1. 链式队

void DequePrint(Deque* d)//打印队列元素
{
	assert(d);
	DuListNode* cur = d->front;
	DuListNode* tail = d->rear;
	printf("队头:");
	while (cur != tail->next)
	{
		printf("%d<=>", cur->data);
		cur = cur->next;
	}
	printf("队尾\n");
}

12.2. 循环队

void DequePrint(Deque* d)//打印队列元素
{
	assert(d);
	int cur = d->front;
	printf("队头->");
	while (cur != d->rear)
	{
		printf("%d->", d->data[cur]);
		cur = (cur + 1) % MAXSIZE;
	}
	printf("队尾\n");

}

12.3. 复杂度分析

  • 时间复杂度:无论是链式队还是循环队列都需要遍历这个队列,所以时间复杂度为O(N)。
  • 空间复杂度:无论是链式队还是循环队列花费空间都是一个固定大小,所以空间复杂度为O(1)

13. 销毁队列

13.1. 链式队

void DequeDestroy(Deque* d)//销毁队列
{
	assert(d);
	DuListNode* cur = d->front;
	while (cur)
	{
		DuListNode* del = cur;
		cur = cur->next;
		free(del);
		del = NULL;
	}
	d->front = d->rear = NULL;
}

13.2. 循环队

void DequeDestroy(Deque* d)//销毁队列
{
	assert(d);
	free(d->data);
	d->data = NULL;
	d->front = d->rear = 0;
}

13.3. 复杂度分析

  • 时间复杂度:无论是链式队还是循环队列花费时间都是一个常数,所以时间复杂度为O(1)。
  • 空间复杂度:无论是链式队还是循环队列花费空间都是一个固定大小,所以空间复杂度为O(1)

14. 对比与应用

14.1. 对比

双向队列的两种实现方式的效果与普通队列实现差不多,这里就不在一一赘述。

14.2. 应用

双向队列兼备队列与栈的性质,所以可以应用于这两种数据结构的所有应用场景。

此外它应用于撤销的一种情景:通常情况下,撤销是以栈的方式实现,当我们每次更改时就入栈,撤销就出栈。但是我们知道系统给与栈的空间是有限的,我们不可能一直入栈。当入栈超过一个限度时,我们就用过删除栈底的数据,这时栈这个数据结构就无法满足需求。所以这时我们可以使用双向队列来实现。

15. 完整代码

15.1. 链式队

15.1.1. Deque.h
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>
typedef int QDataType;
typedef struct DuListNode
{
	QDataType data;
	struct Node* prev;
	struct Node* next;
}DuListNode;

typedef struct Deque
{
	size_t size;
	DuListNode* front;
	DuListNode* rear;
}Deque;
void DequeInit(Deque* d);//初始化
bool DequeEmpty(Deque* d);//判断是否为空
QDataType DequeFront(Deque* d);//获取队头元素
QDataType DequeBack(Deque* d);//获取队尾元素
size_t DequeSize(Deque* d);//获取队列长度
void DequeFrontPush(Deque* d, QDataType x);//队首入队
void DequeRearPush(Deque* d, QDataType x);//队尾入队
void DequeFrontPop(Deque* d);//队首出队
void DequeRearPop(Deque* d);//队尾出队
void DequePrint(Deque* d);//打印队列元素
void DequeDestroy(Deque* d);//销毁队列
15.1.2. Deque.c
#define _CRT_SECURE_NO_WARNINGS 1
#include"Deque.h"
void DequeInit(Deque* d)//初始化
{
	assert(d);
	d->front = NULL;
	d->rear = NULL;
	d->size = 0;
}
bool DequeEmpty(Deque* d)//判断是否为空
{
	assert(d);
	return (d->front == NULL) && (d->rear == NULL);
}
QDataType DequeFront(Deque* d)//获取队头元素
{
	assert(d);
	assert(!DequeEmpty(d));
	return d->front->data;
}
QDataType DequeBack(Deque* d)//获取队尾元素
{
	assert(d);
	assert(!DequeEmpty(d));
	return d->rear->data;
}
size_t DequeSize(Deque* d)//队列长度
{
	return d->size;
}
void DequeFrontPush(Deque* d, QDataType x)//队首入队
{
	assert(d);
	DuListNode* newnode = (DuListNode*)malloc(sizeof(DuListNode));
	if (newnode == NULL)
	{
		perror("malloc fail");
		return;
	}
	newnode->data = x;
	newnode->next = NULL;
	newnode->prev = NULL;
	if (d->front == NULL)
	{
		d->front = d->rear = newnode;
	}
	else
	{
		d->front->prev = newnode;
		newnode->next = d->front;
		d->front = newnode;
	}
    d->size++;
}
void DequeRearPush(Deque* d, QDataType x)//队尾入队
{
	assert(d);
	DuListNode* newnode = (DuListNode*)malloc(sizeof(DuListNode));
	if (newnode == NULL)
	{
		perror("malloc fail");
		return;
	}
	newnode->data = x;
	newnode->next = NULL;
	newnode->prev = NULL;
	if (d->front == NULL)
	{
		d->front = d->rear = newnode;
	}
	else
	{
		d->rear->next = newnode;
		newnode->prev = d->rear;
		d->rear = newnode;
	}
	d->size++;
}
void DequeFrontPop(Deque* d)//队首出队
{
	assert(d);
	assert(!DequeEmpty(d));
	//1.只有一个结点
	if (d->front == d->rear)
	{
		free(d->front);
		d->front = d->rear = NULL;
	}
	//2.有多个结点
	else
	{
		DuListNode* next = d->front->next;
		next->prev = NULL;
		d->front->next = NULL;
		free(d->front);
		d->front = next;
	}
	d->size--;
}
void DequeRearPop(Deque* d)//队尾出队
{
	assert(d);
	assert(!DequeEmpty(d));
	//1.只有一个结点
	if (d->front == d->rear)
	{
		free(d->front);
		d->front = d->rear = NULL;
	}
	else
	{
		DuListNode* prev = d->rear->prev;
		prev->next = NULL;
		d->rear->prev = NULL;
		free(d->rear);
		d->rear = prev;
	}
    d->size--;
}
void DequePrint(Deque* d)//打印队列元素
{
	assert(d);
	DuListNode* cur = d->front;
	DuListNode* tail = d->rear;
	printf("队头:");
	while (cur != tail->next)
	{
		printf("%d<=>", cur->data);
		cur = cur->next;
	}
	printf("队尾\n");
}
void DequeDestroy(Deque* d)//销毁队列
{
	assert(d);
	DuListNode* cur = d->front;
	while (cur)
	{
		DuListNode* del = cur;
		cur = cur->next;
		free(del);
		del = NULL;
	}
	d->front = d->rear = NULL;
}

15.2. 循环队

15.2.1. Deque.h
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>
typedef int QDataType;
#define MAXSIZE 50  //定义元素的最大个数
typedef struct {
    QDataType *data;
    int front;  //头指针
    int rear;   //尾指针
}Deque;

void DequeInit(Deque* d);//初始化
bool DequeEmpty(Deque* d);//判断是否为空
bool DequeFull(Deque* d);//判断队列是否满
QDataType DequeFront(Deque* d);//获取队头元素
QDataType DequeBack(Deque* d);//获取队尾元素
size_t DequeSize(Deque* d);//获取队列长度
void DequeFrontPush(Deque* d, QDataType x);//队首入队
void DequeRearPush(Deque* d, QDataType x);//队尾入队
void DequeFrontPop(Deque* d);//队首出队
void DequeRearPop(Deque* d);//队尾出队
void DequePrint(Deque* d);//打印队列元素
void DequeDestroy(Deque* d);//销毁队列
15.2.2. Deque.c
void DequeInit(Deque* d)//初始化
{
	d->data = (QDataType*)malloc(sizeof(QDataType )* MAXSIZE);
	if (d->data == NULL)
	{
		perror("malloc fail:");
		return;
	}
	d->front = 0;
	d->rear = 0;
}
bool DequeEmpty(Deque* d)//判断是否为空
{
	assert(d);
	return d->front == d->rear;
}
bool DequeFull(Deque* d)//判断队列是否满
{
	assert(d);
	return (d->rear + 1) % MAXSIZE == d->front;
}
QDataType DequeFront(Deque* d)//获取队头元素
{
	assert(d);
	assert(!DequeEmpty(d));
	return d->data[d->front];
}
QDataType DequeBack(Deque* d)//获取队尾元素
{
	assert(d);
	assert(!DequeEmpty(d));
	return d->data[(d->rear-1+MAXSIZE)%MAXSIZE];
}
size_t DequeSize(Deque* d)//获取队列长度
{
	assert(d);
	return (d->rear - d->front + MAXSIZE) % MAXSIZE;
}
void DequeFrontPush(Deque* d, QDataType x)//队首入队
{
	assert(d);
	if (DequeFull(d))
	{
		printf("队列已满\n");
		return;
	}
	d->data[(d->front - 1 + MAXSIZE) % MAXSIZE]=x;
	d->front = (d->front - 1 + MAXSIZE) % MAXSIZE;
}
void DequeRearPush(Deque* d, QDataType x)//队尾入队
{
	assert(d);
	if (DequeFull(d))
	{
		printf("队列已满\n");
		return;
	}
	d->data[d->rear] = x;
	d->rear = (d->rear + 1) % MAXSIZE;
}
void DequeFrontPop(Deque* d)//队首出队
{
	assert(d);
	assert(!DequeEmpty(d));
	d->front = (d->front + 1) % MAXSIZE;
}
void DequeRearPop(Deque* d)//队尾出队
{
	assert(d);
	assert(!DequeEmpty(d));
	d->rear = (d->rear - 1+MAXSIZE) % MAXSIZE;
}
void DequePrint(Deque* d)//打印队列元素
{
	assert(d);
	int cur = d->front;
	printf("队头->");
	while (cur != d->rear)
	{
		printf("%d->", d->data[cur]);
		cur = (cur + 1) % MAXSIZE;
	}
	printf("队尾\n");

}
void DequeDestroy(Deque* d)//销毁队列
{
	assert(d);
	free(d->data);
	d->data = NULL;
	d->front = d->rear = 0;
}

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

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

相关文章

Ant Design Pro | 前端项目初始化

初始化项目 环境确认 这里使用的版本如下&#xff1a; 新建文件夹&#xff08;fapi&#xff09; 执行项目初始化命令 cmd进入命令行执行项目初始化命令&#xff0c;参考官网https://pro.ant.design/zh-CN/ # 使用 npm npm i ant-design/pro-cli -g # fapi-frontend是项目…

树莓派固件烧录教程(2024)

一、烧录工具准备 硬件准备&#xff1a; 16G及以上TF卡和读卡器&#xff0c;TF卡建议高速卡&#xff08;卡的读写速度直接影响树莓派的运行速度&#xff09;。 软件准备&#xff1a;&#xff08;下面二方法选其一即可&#xff09; 方法1&#xff1a;raspberry官方烧录工具R…

【高校科研前沿】中国科学院南京地理与湖泊研究所肖启涛博士为一作在Sci. Bull发文:我国湖泊二氧化碳从大气的源向汇转变

目录 1.文章简介 2.研究内容 3.文章引用 1.文章简介 论文名称&#xff1a;Lakes shifted from a carbon dioxide source to a sink over past two decades in China 第一作者及通讯作者&#xff1a;肖启涛&#xff08;博士生&#xff09;&#xff0c;段洪涛&#xff08;研究…

JavaSE继承和多态(下)

在了解多态之前我们先弄清以下三个概念&#xff1a; 方法的重写向上转型和向下转型动态绑定和静态绑定 一.方法的重写 重写(override)&#xff1a;也称为覆盖。重写是子类对父类非静态、非private修饰&#xff0c;非final修饰&#xff0c;非构造方法等的实现过程 进行重新编写,…

如何使用 langchain 与 openAI 连接

上一篇写了如何安装 langchain https://www.cnblogs.com/hailexuexi/p/18087602 这里主要说一个 langchain的使用 创建一个目录 langchain &#xff0c;在这个目录下创建两个文件 main.py 这段python代码&#xff0c;用到了openAI&#xff0c;需要openAI及FQ。这里只做…

c++的学习之路:16、string(3)

上章有一些东西当时没学到&#xff0c;这里学到了将在补充&#xff0c;文章末附上代码&#xff0c;思维导图。 目录 一、赋值重载 二、带模板的创建 三、析构函数 四、代码 五、思维导图 一、赋值重载 这里的赋值重载就是直接利用交换函数进行把传参生成的临时数据和需要…

IDEA中的Debug功能介绍

说明&#xff1a;本文介绍IDEA中的Debug功能&#xff0c;基于2023.2&#xff08;Ultimate Edition&#xff09;版本 简单介绍 首先&#xff0c;在程序需要停止的所在行号上&#xff0c;鼠标左键&#xff0c;可设置一个断点&#xff0c;是一个红色圆点标志&#xff0c;表示程序…

2023年下半年中级软件设计师上午真题及答案解析

01 02 03 04 05 06 07 08 09 10 篇幅有限&#xff0c;私我获取免费完整 pdf文件

php反序列化题目

[NewStarCTF 公开赛赛道]UnserializeOne 分析代码&#xff0c;最终需要调用到 file_get_contents 即可获得flag 从后往前分析 触发 __invoke 需要 以调用函数的方式调用一个对象 可以找到Start类 里的__isset中可以将类当作函数调用 所以需要调用到 __isset 就需要 isset()…

Steam上线真人乙游,女性玩家还愿意买单吗?

Steam上线了一款真人乙游《糟糕&#xff01;他们太爱我了怎么办&#xff1f;》&#xff08;以下简称《糟糕&#xff01;&#xff09;。 乍一听这个游戏名&#xff0c;似乎和《完蛋&#xff01;我被美女包围了&#xff01;》有异曲同工之妙&#xff0c;事实也确实如此&#xff…

实现通讯录(顺序表版本)

一、功能要求 &#xff08;1&#xff09;⾄少能够存储100个⼈的通讯信息 &#xff08;2&#xff09;能够保存⽤⼾信息&#xff1a;名字、性别、年龄、电话、地址等 &#xff08;3&#xff09;增加联系⼈信息 &#xff08;4&#xff09;删除指定联系⼈ &#xff08;5&#…

国内:深圳交通流量数据集

数据来源&#xff1a;深圳政府数据开放平台&#xff08;深圳市政府数据开放平台&#xff09;&#xff0c;这个官网上还有其他类数据集&#xff0c;值得收藏&#xff01;&#xff01;&#xff01; 数据集介绍&#xff1a;宝安区-G4高速西乡大道入口车流量统计 第一行每列的标题…

什么是超导悬浮?工作原理是什么?

某些材料在冷却到某个温度&#xff08;也称为“临界温度”&#xff09;以下时会完全失去电阻。 1910 年&#xff0c;一位名叫 Heike Kamerlingh Onnes 的荷兰物理学家发现了这一现象。他注意到低于一定温度时电阻突然下降&#xff0c;然后他大胆地声称发现了一种新的物质状态&a…

字符串处理

读取 先定义&#xff1a; char ch[100];string s; cin>>s或cin>>ch以空格或换行符结束gets(ch);//gets只能读字符数组&#xff0c;不能直接读字符串stringgets和getline会把第一次出现的换行符及先前的字符串读进去&#xff08;包括空格&#xff09;&#xff0…

利用Flutter框架实现iOS应用的跨平台发布策略

本文探讨了使用Flutter开发的iOS应用能否上架&#xff0c;以及上架的具体流程。苹果提供了App Store作为正式上架渠道&#xff0c;同时也有TestFlight供开发者进行内测。合规并通过审核后&#xff0c;Flutter应用可以顺利上架。但上架过程可能存在一些挑战&#xff0c;因此可能…

【Linux】正则表达式实验操作实例

正则表达式是一种强大的工具&#xff0c;用于在文本中查找、匹配和替换特定的字符串模式。 实验目的 掌握正则表达式的表达方式掌握grep/egrep命令的用法掌握sed 命令的用法掌握awk命令的用法 正则表达式 实验目的实验内容实验过程创建grep文件来进行如下操作用sed命令完成下列…

HAL STM32 定时器PWM DMA输出方式

HAL STM32 定时器PWM DMA输出方式 &#x1f9e8;遗留问题&#xff1a;当配置RCR重复计数器&#xff0c;配置为2时&#xff0c;在定义了3组PWM参数情况下&#xff0c;只能输出第二组参数的PWM波形。&#xff08;HAL_TIM_PWM_Start_DMA(&htim1, TIM_CHANNEL_1, aCCValue_Buff…

Java中网络编程,Junit单元测试详解

文章目录 软件结构C/S结构B/S结构 概述三要素IP &#xff08;银行的位置&#xff09;端口 (银行中某个柜台号)协议 (填写取款单的规则)TCP通信程序TCP通信原理客户端发送数据服务端接收数据过程图三次握手 Junit单元测试概述常见的注解使用断言概述使用 软件结构 C/S结构 客户…

怀俄明探空站数据解算PWV和Tm

1. Matlab 获取代码可关注公众号WZZHHH回复&#xff08;怀俄明探空站数据解算PWV和Tm&#xff09;&#xff0c;或者咸鱼关注&#xff1a;WZZHHH123 怀俄明探空站数据解算PWV和Tm&#xff1a; 有关 Matlab 获取代码可关注公众号WZZHHH回复&#xff08;怀俄明多线程下载&#…

mysql_secure_installation初始化数据库报Access denied

使用mysql_secure_installation配置时出错&#xff1a; 可能输入密码错误&#xff0c;重新复制&#xff0c;粘贴密码。 或者&#xff1a; 登录mysql&#xff0c;设置密码&#xff0c;然后再设置权限。 mysql -u root -p [输入密码] sql>set passwordpassword("newPa…