队列(8.6)

news2025/1/1 8:33:20

目录

2.队列

2.1队列的概念及结构

2.2队列的实现

2.2.1初始化队列

2.2.2队尾入队列

2.2.3队头出队列

2.2.4获取队列头部元素

2.2.5 销毁队列

3.栈和队列面试题

225. 用队列实现栈 - 力扣(LeetCode)

232. 用栈实现队列 - 力扣(LeetCode)

​编辑

622. 设计循环队列 - 力扣(LeetCode)

​编辑


2.队列

2.1队列的概念及结构

队列的特性与栈恰恰相反, 先进先出
实现方式上有数组和链表,链表更有优势,因为数组取元素的时候比较麻烦。
应用场景有公平性排队(抽号机),BFS(广度优先遍历)等。
将队列运用于抽号机能够计算出排队需要的等待的时间,需要等待前面的人数等信息,也能实现叫号(取队头)操作,能够实现绝对的公平,不存在插队现象。

2.2队列的实现

队列的实现通过不带头单向不循环链表,同时需要头节点和尾节点来管理入队列和出队列。

2.2.1初始化队列

push操作头节点和尾节点都需要改变,因此我们额外用一个结构体更方便来管理这两个指针,顺便在结构体中添加队列成员个数size,以便需要个数的时候直接使用。
// 初始化队列
void QueueInit(Que* pq)
{
	assert(pq);
	pq->head = pq->tail = NULL;
	pq->size = 0;
}

2.2.2队尾入队列

原理同之前的链表操作完全相同
// 队尾入队列
void QueuePush(Que* pq, QDataType x)
{
	assert(pq);
	//开辟新节点
	QNode* newnode = (QNode*)malloc(sizeof(QNode));
	if (newnode == NULL)
	{
		perror("malloc");
		exit(-1);
	}
	//初始化新节点
	newnode->data = x;
	newnode->next = NULL;
	//判断队列是否为空
	if (pq->tail == NULL)
	{
		pq->head = pq->tail = newnode;
	}
	//不为空尾插
	else
	{
		pq->tail->next = newnode;
		pq->tail = newnode;
	}
}

2.2.3队头出队列

如果列表只剩一个成员,我们就需要释放掉这个成员的空间后将头尾节点置空。
// 队头出队列
void QueuePop(Que* pq)
{
	assert(pq);
	//列表不能为空
	assert(!QueueEmpty(pq));
	//如果列表只剩一个成员
	if (pq->head->next == NULL)
	{
		free(pq->head);
		pq->head = pq->tail = NULL;
	}
	//正常头删
	else
	{
		QNode* next = pq->head->next;
		free(pq->head);
		pq->head = next;
	}
	pq->size--;
}

2.2.4获取队列头部元素

// 获取队列头部元素
QDataType QueueFront(Que* pq)
{
	assert(pq);
	//检查列表不为空
	assert(!QueueEmpty(pq));

	return pq->head->data;
}

// 检测队列是否为空,如果为空返回非零结果,如果非空返回0 
int QueueEmpty(Que* pq)
{
	assert(pq);
	//列表为空返回1,不为空返回0
	return pq->head == NULL;
}

2.2.5 销毁队列

// 销毁队列
void QueueDestroy(Que* pq)
{
	assert(pq);

	QNode* cur = pq->head;
	while (cur)
	{
		QNode* next = cur->next;
		free(cur);
		cur = next;
	}
	pq->head = pq->tail = NULL;
	pq->size = 0;
}

2.2.6 探空

// 检测队列是否为空,如果为空返回非零结果,如果非空返回0 
int QueueEmpty(Que* pq)
{
	assert(pq);
	//列表为空返回1,不为空返回0
	return pq->head == NULL;
}

3.栈和队列面试题

225. 用队列实现栈 - 力扣(LeetCode)

分析:
创建两个队列
入队列:入不为空的队列
出队列:出不为空的前n-1个元素,插入到空队列,删除剩余元素
队列的基本操作复用上面的代码
typedef int QDataType;

typedef struct QueueNode
{
	QDataType data;
	struct QueueNode* next;
	
}QNode;
typedef struct Que
{
	QNode* head;
	QNode* tail;
	int size;
}Que;

// 初始化队列
void QueueInit(Que* pq);
// 队尾入队列
void QueuePush(Que* pq, QDataType x);
// 队头出队列
void QueuePop(Que* pq);
// 获取队列头部元素
QDataType QueueFront(Que* pq);
// 获取队列队尾元素
QDataType QueueBack(Que* pq);
// 检测队列是否为空,如果为空返回非零结果,如果非空返回0 
int QueueEmpty(Que* pq);
// 销毁队列
void QueueDestroy(Que* pq);
//队列节点数
int QueueSize(Que* pq);

// 初始化队列
void QueueInit(Que* pq)
{
	assert(pq);
	pq->head = pq->tail = NULL;
	pq->size = 0;
}

// 队尾入队列
void QueuePush(Que* pq, QDataType x)
{
	assert(pq);
	//开辟新节点
	QNode* newnode = (QNode*)malloc(sizeof(QNode));
	if (newnode == NULL)
	{
		perror("malloc");
		exit(-1);
	}
	//初始化新节点
	newnode->data = x;
	newnode->next = NULL;
	//判断队列是否为空
	if (pq->tail == NULL)
	{
		pq->head = pq->tail = newnode;
		pq->size++;
	}
	//不为空尾插
	else
	{
		pq->tail->next = newnode;
		pq->tail = newnode;
		pq->size++;
	}
}

// 队头出队列
void QueuePop(Que* pq)
{
	assert(pq);
	//列表不能为空
	assert(!QueueEmpty(pq));
	//如果列表只剩一个成员
	if (pq->head->next == NULL)
	{
		free(pq->head);
		pq->head = pq->tail = NULL;
	}
	//正常头删
	else
	{
		QNode* next = pq->head->next;
		free(pq->head);
		pq->head = next;
	}
	pq->size--;
}

// 获取队列头部元素
QDataType QueueFront(Que* pq)
{
	assert(pq);
	//检查列表不为空
	assert(!QueueEmpty(pq));

	return pq->head->data;
}

// 获取队尾元素
QDataType QueueBack(Que* pq)
{
	assert(pq);
	//检查列表不为空
	assert(!QueueEmpty(pq));

	return pq->tail->data;
}

// 检测队列是否为空,如果为空返回非零结果,如果非空返回0 
int QueueEmpty(Que* pq)
{
	assert(pq);
	//列表为空返回1,不为空返回0
	return pq->head == NULL;
}
// 销毁队列
void QueueDestroy(Que* pq)
{
	assert(pq);

	QNode* cur = pq->head;
	while (cur)
	{
		QNode* next = cur->next;
		free(cur);
		cur = next;
	}
	pq->head = pq->tail = NULL;
	pq->size = 0;
}
//队列节点数
int QueueSize(Que* pq)
{
	assert(pq);

	return pq->size;
}

//定义列表的结构体
typedef struct {
    Que q1;
    Que q2;
} MyStack;
//列表初始化
MyStack* myStackCreate() {
    //不能直接初始化,临时变量,出函数销毁,需要开辟空间
    MyStack* pst=(MyStack*)malloc(sizeof(MyStack));
    //参数为队列的指针
    QueueInit(&pst->q1);
    QueueInit(&pst->q2);

    return pst;
}

void myStackPush(MyStack* obj, int x) {
    //谁不为空push到谁
    if(!QueueEmpty(&obj->q1))
    {
        QueuePush(&obj->q1,x);
    }
    else
    {
        QueuePush(&obj->q2,x);
    }
}
//出栈
int myStackPop(MyStack* obj) {
    //随便假设一个为空队列,一个为非空
    Que* empty=&obj->q1;
    Que* nonempty=&obj->q2;
    //如果假设错误,就交换
    if(!QueueEmpty(&obj->q1))
    {
        nonempty=&obj->q1;
        empty=&obj->q2;
    }
		//将非空栈出到剩尾元素为止
    while(QueueSize(nonempty)>1)
    {
			  //非空栈入到空栈
        QueuePush(empty,QueueFront(nonempty));
				//入一个出一个
        QueuePop(nonempty);
    }
		//保存尾元素
    int top=QueueFront(nonempty);
		//出掉尾元素
    QueuePop(nonempty);

    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);
*/

232. 用栈实现队列 - 力扣(LeetCode)

栈的特性是先后进先出,队列的特性是先进先出;若想用栈实现先进先出,就需要另创建一个栈,将原栈中的数据倒过去就能够轻松实现。

原栈中的数据倒过去之后,此时插入数据,直接插入到原栈中,用原栈专门用来接收数据,如果再出栈,用一个栈专门出栈,当专门出栈的栈出空之后,再从原栈倒数据过来;而不用每次出栈都把数据倒出去又倒回来,很麻烦。

typedef int STDataType;
//支持动态增长的栈
typedef struct Stack
{
	STDataType* a;
	int top;//栈顶
	int capacity;//容量
}ST;

// 初始化栈
void STInit(ST* ps);
// 入栈
void STPush(ST* ps, STDataType x);
// 出栈
void STPop(ST* ps);
// 获取栈顶元素
STDataType STTop(ST* ps);
// 获取栈中有效元素个数
int STSize(ST* ps);
// 检测栈是否为空,如果为空返回非零结果,如果不为空返回0 
bool STEmpty(ST* ps);
// 销毁栈
void STDestroy(ST* ps);

void STInit(ST* ps)
{
	assert(ps);
	ps->a = NULL;
	ps->capacity = 0;
	ps->top = 0;
}

void STDestroy(ST* ps)
{
	assert(ps);

	free(ps->a);
	ps->a = NULL;
	ps->top = ps->capacity = 0;
}

void STPush(ST* ps, STDataType x)
{
	assert(ps);
	// 11:40
	if (ps->top == ps->capacity)
	{
		int newCapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
		STDataType* tmp = (STDataType*)realloc(ps->a, sizeof(STDataType) * newCapacity);
		if (tmp == NULL)
		{
			perror("realloc fail");
			exit(-1);
		}

		ps->a = tmp;
		ps->capacity = newCapacity;
	}

	ps->a[ps->top] = x;
	ps->top++;
}

void STPop(ST* ps)
{
	assert(ps);

	// 
	assert(ps->top > 0);

	--ps->top;
}

STDataType STTop(ST* ps)
{
	assert(ps);

	// 
	assert(ps->top > 0);

	return ps->a[ps->top - 1];
}

int STSize(ST* ps)
{
	assert(ps);

	return ps->top;
}

bool STEmpty(ST* ps)
{
	assert(ps);

	return ps->top == 0;
}

//定义两个栈类型
typedef struct {
    ST pushst;
    ST popst;
} MyQueue;

//开辟并初始化结构体变量
MyQueue* myQueueCreate() {
    MyQueue* obj=(MyQueue*)malloc(sizeof(MyQueue));
    STInit(&obj->pushst);
    STInit(&obj->popst);

    return obj;
}

void myQueuePush(MyQueue* obj, int x) {
    //始终往push栈上面push
    STPush(&obj->pushst,x);
}
//出队列
int myQueuePop(MyQueue* obj) {
    
    int front=myQueuePeek(obj);
    //与peek唯一不同之处就是取得队头后删掉
    STPop(&obj->popst);
    return front;
}
//取队头数据
int myQueuePeek(MyQueue* obj) {
    if(STEmpty(&obj->popst))
    {
        //pop为空,从push倒数据
        while(!STEmpty(&obj->pushst))
        {
            //pop入一个
            STPush(&obj->popst,STTop(&obj->pushst));
            //push出一个
            STPop(&obj->pushst);
        }
    }
    //不为空,直出
    return STTop(&obj->popst);
}

bool myQueueEmpty(MyQueue* obj) {
    //两个栈都为空才为空
    return STEmpty(&obj->pushst)&&STEmpty(&obj->popst);
}

void myQueueFree(MyQueue* obj) {
    STDestroy(&obj->pushst);
    STDestroy(&obj->popst);
    
    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);
*/

622. 设计循环队列 - 力扣(LeetCode)

我们用数组来实现,给数组多开一个 rear 空间(不存数据)用来解决探空和探满的问题

front 为列表头节点的下标,rear 为为尾节点的下一个节点的下标;front 和rear 初始值为0,push 一次 rear ++一次,由于列表是定长的,因此当push 了k个数据时,列表就放满了,不能再入数据。放满的标志为此时列表的实际长度(包括 rear节点)对理论长度 k+1 取余的结果等于 front 。

pop操作,我们直接让 front ++,遵循先进先出的原则。

push 操作,push 一次,rear 向后移动一次,直到 rear 的下一个为 front ,则代表放满,标志依然为(rear+1)%(k+1)=front ,当rear<k,就等于 rear +1= front。

此时再 pop 到 front 处于数组末尾,继续 pop,front 就转到数组开头,当 rear 和 front 重合且为空时,数组就为空。



//定义队列
typedef struct {
    //数组
    int *a;
    //头
    int front;
    //尾
    int rear;
    //数组长度(不包含rear)
    int k;
} MyCircularQueue;
//初始化队列
MyCircularQueue* myCircularQueueCreate(int k) {
     //为队列开空间
     MyCircularQueue* obj=(MyCircularQueue*)malloc(sizeof(MyCircularQueue));
     //为数组开空间,多开一个rear用于探空(满)
     obj->a=(int*)malloc(sizeof(int)*(k+1));
     obj->front=obj->rear=0;
     obj->k=k;

     return obj;
}
//探空(非0为空,0为非空)
bool myCircularQueueIsEmpty(MyCircularQueue* obj) {
    //front和rear相等就是空
    return obj->front==obj->rear;
    
}
//探满(非0为满,0为未满)
bool myCircularQueueIsFull(MyCircularQueue* obj) {
    //rear的下一个为front为满;rear在队尾,front在对头为满。
    return (obj->rear+1)%(obj->k+1)==obj->front;

}
//插入
bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {
    //先探满
    if(myCircularQueueIsFull(obj))
    {
        return false;
    }
    //正常情况下往rear位置放数据,放完后移
    obj->a[obj->rear]=value;
    obj->rear++;
    //如果rear走到队尾之后(++之后等于k),那么++之后应该挪到队头(归0,因此取模)
    //取模操作在走过队尾之前无效
    obj->rear%=(obj->k+1);

    return true;
}
//删除
bool myCircularQueueDeQueue(MyCircularQueue* obj) {
    //先探空
    if(myCircularQueueIsEmpty(obj))
    {
        return false;
    }
    //正常情况下front后移
    obj->front++;
    //如果front走到队尾之后(++之后等于k),那么++之后应该挪到队头(归0,因此取模)
    obj->front%=(obj->k+1);

    return true;
}
//取头
int myCircularQueueFront(MyCircularQueue* obj) {
    //探空
    if(myCircularQueueIsEmpty(obj))
    {
        return -1;
    }
    else
    {
        return obj->a[obj->front];
    }
}
//取尾(取rear的上一个节点)
int myCircularQueueRear(MyCircularQueue* obj) {
    //探空
    if(myCircularQueueIsEmpty(obj))
    {
        return -1;
    }
    else
    {
        //+k并对k+1取余,当rear在队头,上一个节点就在队尾
        //不在队头时取余结果刚好为上一个节点
        return obj->a[(obj->rear+obj->k)%(obj->k+1)];
    }

}

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);
*/

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

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

相关文章

【送书福利-第二十一期】《ChatGPT进阶:提示工程入门》

&#x1f60e; 作者介绍&#xff1a;我是程序员洲洲&#xff0c;一个热爱写作的非著名程序员。CSDN全栈优质领域创作者、华为云博客社区云享专家、阿里云博客社区专家博主、前后端开发、人工智能研究生。公粽号&#xff1a;程序员洲洲。 &#x1f388; 本文专栏&#xff1a;本文…

正点原子嵌入式linux驱动开发——Linux 多点电容触摸屏

随着智能手机的发展&#xff0c;电容触摸屏也得到了飞速的发展。相比电阻触摸屏&#xff0c;电容触摸屏有很多的优势&#xff0c;比如支持多点触控、不需要按压&#xff0c;只需要轻轻触摸就有反应。ALIENTEK的三款RGB LCD屏幕都支持多点电容触摸&#xff0c;本章就以ATK7016这…

Spring Cloud Alibaba Seata 实现 SAGA 事物

Seata 是一款开源的分布式事务解决方案&#xff0c;致力于提供高性能和简单易用的分布式事务服务。Seata 将为用户提供了 AT、TCC、SAGA 和 XA 事务模式&#xff0c;为用户打造一站式的分布式解决方案 Seata 官网&#xff1a;https://seata.io/zh-cn/ Spring Cloud Alibaba 官…

【Java网络原理】 六

本文主要介绍了网络层的IP协议/NAT机制/IPv6的由来以及在数据链路层涉及到的以太网协议和DNS域名解析系统 一.网络层 1.IP协议 各个字段所表示的含义 >4位版本号 用来表示IP协议的版本&#xff0c;现在只有两个版本IPv4 &#xff0c;IPv6 >4位首部长度 IP报头可变&…

【自然语言处理】【长文本处理】RMT:能处理长度超过一百万token的Transformer

相关博客 【自然语言处理】【长文本处理】RMT&#xff1a;能处理长度超过一百万token的Transformer 【自然语言处理】【大模型】MPT模型结构源码解析(单机版) 【自然语言处理】【大模型】ChatGLM-6B模型结构代码解析(单机版) 【自然语言处理】【大模型】BLOOM模型结构源码解析(…

AI直播换脸——DeepFaceLab 3.0模型训练与微调

前言 DeepFaceLab是一种基于深度学习的人脸合成和转换工具。它使用了深度神经网络来分析和修改图像中的人脸部分&#xff0c;可以实现将一个人的脸部特征应用到另一个人的照片上&#xff0c;或者进行面部表情、年龄、性别等特征的变换。 DeepFaceLab具备一系列核心功能&#x…

Matplotlib详解(plt 和ax分别是什么)

Matplotlib中的plt 和 ax 分别是什么&#xff1f; 概念引入两种绘图方式的区别subplot 绘制Matplotlib 常见组件设置整理4.1 设置显示中文字体4.2 设置标题4.3 边框的显示问题4.4 图例设置&#xff08;legend&#xff09;4.5 图形与边框之间的留白控制4.6 设置双坐标轴4.7 坐标…

Java毕业设计 SpringBoot 新能源充电桩管理系统

Java毕业设计 SpringBoot 新能源充电桩管理系统 SpringBoot 新能源充电桩管理系统 功能介绍 管理员 登录 验证码 注册 系统用户管理 普通用户管理 通知公告管理 留言管理 充电站管理 充电桩管理 充电桩预约 充电管理 订单管理 修改密码 普通用户 登录 修改个人资料 通知公告…

椭圆曲线在SM2中的应用(三)

一、SM2加密运算 1.1加密原始数据 SM2加密运算首先是用户A对数据加密,用户A拥有原始数据 椭圆曲线系统参数长度为klen比特的消息M公钥Pb椭圆曲线系统参数,已经在 椭圆曲线参数(二)中详细介绍;M就是需要加密消息,长度为klen; 1.1.1 公钥Pb的计算方式 公钥Pb=dBG,其中…

elasticsearch一些重要的配置参数

先看一下官网给我们提供的全部的参数配置项 官网地址 官方文档链接&#xff1a;注意版本是8.1Configuring Elasticsearch | Elasticsearch Guide [8.1] | Elastic​编辑https://www.elastic.co/guide/en/elasticsearch/reference/current/settings.html 重要&#xff08;基本…

40.弗洛伊德(Floyd)算法

概述 我们此前拆解过迪杰斯特拉&#xff08;Dijkstra&#xff09;算法&#xff0c;与它一样&#xff0c;弗洛伊德&#xff08;Floyd&#xff09;算法也是用于寻找给定的加权图中顶点间最短路径的算法。该算法是1978年图灵奖获得者、斯坦福大学计算机科学系教授罗伯特弗洛伊德及…

【Linux】centos安装配置及远程连接工具的使用

&#x1f389;&#x1f389;欢迎来到我的CSDN主页&#xff01;&#x1f389;&#x1f389; &#x1f3c5;我是Java方文山&#xff0c;一个在CSDN分享笔记的博主。&#x1f4da;&#x1f4da; &#x1f31f;推荐给大家我的专栏《微信小程序开发实战》。&#x1f3af;&#x1f3a…

私有云:【12】使用connention托管虚拟桌面

私有云&#xff1a;【12】使用connention托管虚拟桌面 1、使用connention托管虚拟桌面 1、使用connention托管虚拟桌面 使用cloudadmin用户登录connection服务器 登录connection客户端 创建桌面池 选择手动桌面池 选择vcenter虚拟机 选择vcenter.test.com 按如下选择下一步 设…

贝锐蒲公英旁路模式异地组网,不改动网络实现企业分部与总部互通

Micheal是一家快递公司的IT运维人员&#xff0c;因公司业务发展迅速&#xff0c;新增网点的速度非常快&#xff0c;各网点需将每天的数据都上传到总部服务器&#xff0c;及平时需要向总部服务器查询一些数据&#xff0c;总部的主路由是一台带有防火墙功能的企业路由&#xff0c…

共用体/联合体 的引入

概念 由一系列具有相同数据类型或者不同数据类型的数据组成的集合&#xff0c;数据互斥关系&#xff0c;共用体所有的成员共同使用一份内存空间&#xff0c;其中空间的大小是按照共用体成员中所占的最大的内存空间的成员的空间进行分配&#xff0c;即同一个内存空间存放类型不…

【PyQt学习篇 · ⑤】:QWidget - 鼠标操作

文章目录 鼠标形状设置常用鼠标形状设置自定义鼠标形状 重置形状获取鼠标鼠标跟踪鼠标跟踪案例 鼠标形状设置 常用鼠标形状设置 在PyQt中&#xff0c;QWidget类提供了设置鼠标形状的功能。可以使用setCursor()方法来更改QWidget及其子类的鼠标形状。该方法接受一个Qt.CursorS…

idea的设置

1.设置搜索encoding,所有编码都给换为utf-8 安装插件 eval-reset插件 https://www.yuque.com/huanlema-pjnah/okuh3c/lvaoxt#m1pdA 设置活动模板,idea有两种方式集成tomcat,一种是右上角config配置本地tomcat,一种是插件,如果使用插件集成,则在maven,pom.xml里面加上tomcat…

【uniapp】uniapp实现input输入显示数字键盘:

文章目录 一、官网文档&#xff1a;二、文档&#xff1a;三、效果&#xff1a;【1】number&#xff1a;iPhone原生数字键盘不显示小数点【2】digit&#xff1a;【3】digit和inputmode&#xff1a; 一、官网文档&#xff1a; input | uni-app官网 二、文档&#xff1a; 三、效果…

深度学习中Transformer的简单理解

Transformer 网络结构 Transformer也是由编码器和解码器组成的。 每一层Encoder编码器都由很多层构成的&#xff0c;编码器内又是self-attention和前馈网络构成的。Self-attention是用来做加权平均&#xff0c;前馈网络用来组合。 但是decoder有点不同&#xff0c;多了一层En…

Vue 3 响应式对象:ref 和 reactive 的使用和区别

&#x1f389;&#x1f389;欢迎来到我的CSDN主页&#xff01;&#x1f389;&#x1f389; &#x1f3c5;我是尘缘&#xff0c;一个在CSDN分享笔记的博主。&#x1f4da;&#x1f4da; &#x1f449;点击这里&#xff0c;就可以查看我的主页啦&#xff01;&#x1f447;&#x…