第 3 章 栈和队列 (利用非循环顺序队列采用广度搜索法求解迷宫问题(一条路径))

news2024/11/27 4:38:52

1. 背景说明

广度优先通俗的解释的是将当前所有能走的步骤全部走完并保存在队列中,又称为层序遍历,此外,该方法类似于多条路线并发前进,

哪一条先到就取哪条路线作为结果并终止查询,因此能够得到最短路径,缺点是由于遍历的点太多,效率低下

输入文本

10 10
 
18
 
1 3
1 7
2 3
2 7
3 5
3 6
4 2
4 3
4 4
5 4
6 2
6 6
7 2
7 3
7 4
7 6
7 7
8 1
 
1 1
 
8 8

 

2. 示例代码

1)status.h

/* DataStructure 预定义常量和类型头文件 */

#ifndef STATUS_H
#define STATUS_H

/* 函数结果状态码 */
#define TRUE 					1			/* 返回值为真 */
#define FALSE 					0			/* 返回值为假 */
#define RET_OK 					0			/* 返回值正确 */
#define INFEASIABLE    		   	2			/* 返回值未知 */
#define ERR_MEMORY     		   	3			/* 访问内存错 */
#define ERR_NULL_PTR   			4			/* 空指针错误 */
#define ERR_MEMORY_ALLOCATE		5			/* 内存分配错 */
#define ERR_NULL_STACK			6			/* 栈元素为空 */
#define ERR_PARA				7			/* 函数参数错 */
#define ERR_OPEN_FILE			8			/* 打开文件错 */
#define ERR_NULL_QUEUE			9			/* 队列为空错 */
#define ERR_FULL_QUEUE			10			/* 队列为满错 */
typedef int Status;							/* Status 是函数的类型,其值是函数结果状态代码,如 RET_OK 等 */
typedef int Bollean;						/* Boolean 是布尔类型,其值是 TRUE 或 FALSE */

#endif // !STATUS_H

2) sqQueue.h

/* 顺序队列实现头文件 */

#ifndef SQQUEUE_H
#define SQQUEUE_H

#include "status.h"

#define MAX_QUEUE_SIZE 5

typedef struct {
	int x;
	int y;
	int preOrder;
} QElemType;

typedef struct {
	QElemType *base;
	int front;
	int rear;
} SqQueue;

/* 构造一个空队列 Q */
Status InitQueue(SqQueue *Q);

/* 销毁队列 Q */
Status DestroyQueue(SqQueue *Q);

/* 将 Q 清为空队列 */
void ClearQueue(SqQueue *Q);

/* 若队列 Q 为空队列,则返回 TRUE,否则返回 FALSE */
Bollean QueueEmpty(const SqQueue *Q);

/* 返回 Q 的元素个数,即队列的长度 */
int QueueLength(const SqQueue *Q);

/* 若队列不空,则用 e 返回 Q 的队头元素,并返回 OK */
Status GetQueueHead(const SqQueue *Q, QElemType *e);

/* 插入元素 e 为 Q 的新的队尾元素 */
Status EnQueue(QElemType e, SqQueue *Q);

/* 若队列不空,则删除 Q 的队头元素,用 e 返回其值,并返回 OK */
Status DeQueue(SqQueue *Q, QElemType *e);

/* 从队头到队尾依次对队列 Q 中每个元素调用函数 vi() */
Status QueueTraverse(const SqQueue *Q, void(*vi)(QElemType));

#endif // !SQQUEUE_H

3) sqQueue.c

/* 顺序队列实现源文件 */

#include "sqQueue.h"
#include <stdio.h>
#include <stdlib.h>

static Bollean QueueFull(const SqQueue *Q)
{
	return (Q->rear >= MAX_QUEUE_SIZE) ? TRUE : FALSE;
}

/* 构造一个空队列 Q */
Status InitQueue(SqQueue *Q)
{
	Q->base = (QElemType *)malloc(sizeof(QElemType) * MAX_QUEUE_SIZE);
	if (!Q->base) {
		printf("FuncName: %-15s Line: %-5d ErrorCode: %-3d\n", __func__, __LINE__, ERR_MEMORY_ALLOCATE);
		return ERR_MEMORY_ALLOCATE;
	}

	Q->front = Q->rear = 0;

	return RET_OK;
}

/* 销毁队列 Q */
Status DestroyQueue(SqQueue *Q)
{
	if (Q->base) {
		free(Q->base);
	}

	Q->base = NULL;
	Q->front = Q->rear = 0;

	return RET_OK;
}

/* 将 Q 清为空队列 */
void ClearQueue(SqQueue *Q)
{
	Q->front = Q->rear = 0;
}

/* 若队列 Q 为空队列,则返回 TRUE,否则返回 FALSE */
Bollean QueueEmpty(const SqQueue *Q)
{
	return (Q->front == Q->rear) ? TRUE : FALSE;
}

/* 返回 Q 的元素个数,即队列的长度 */
int QueueLength(const SqQueue *Q)
{
	return (Q->rear - Q->front);
}

/* 若队列不空,则用 e 返回 Q 的队头元素,并返回 OK */
Status GetQueueHead(const SqQueue *Q, QElemType *e)
{
	if (Q->front == Q->rear) {
		printf("FuncName: %-15s Line: %-5d ErrorCode: %-3d\n", __func__, __LINE__, ERR_NULL_QUEUE);
		return ERR_NULL_QUEUE;
	}

	*e = *(Q->base + Q->front);

	return RET_OK;
}

/* 插入元素 e 为 Q 的新的队尾元素 */
Status EnQueue(QElemType e, SqQueue *Q)
{
	if (QueueFull(Q)) {
		Q->base = (QElemType *)realloc(Q->base, sizeof(QElemType) * (unsigned long long)(Q->rear + 1));
		if (!Q->base) {
			printf("FuncName: %-15s Line: %-5d ErrorCode: %-3d\n", __func__, __LINE__, ERR_MEMORY_ALLOCATE);
			return ERR_MEMORY_ALLOCATE;
		}
	}

	Q->base[Q->rear] = e;
	Q->rear = ++(Q->rear);

	return RET_OK;
}

/* 若队列不空,则删除 Q 的队头元素,用 e 返回其值,并返回 OK */
Status DeQueue(SqQueue *Q, QElemType *e)
{
	if (QueueEmpty(Q)) {
		printf("FuncName: %-15s Line: %-5d ErrorCode: %-3d\n", __func__, __LINE__, ERR_NULL_QUEUE);
		return ERR_NULL_QUEUE;
	}

	*e = Q->base[Q->front];
	Q->front = Q->front + 1;

	return RET_OK;
}

/* 从队头到队尾依次对队列 Q 中每个元素调用函数 vi() */
Status QueueTraverse(const SqQueue *Q, void(*vi)(QElemType))
{
	int pos = Q->front;
	while (pos != Q->rear) {
		vi(Q->base[pos]);
		++pos;
	}

	return RET_OK;
}

4) sqStack.h

/* 栈的顺序存储表示头文件 */

#ifndef SQSTACK_H
#define SQSTACK_H

#define STACK_INIT_SIZE 10 		/* 存储空间初始分配量 */
#define STACKINCREMENT 2 		/* 存储空间分配增量 */

#include "status.h"

typedef struct {
	int x;
	int y;
	int preOrder;
} SElemType;

typedef struct SqStack {
	SElemType *base; 			/* 在栈构造之前和销毁之后,base的值为NULL */
	SElemType *top; 			/* 栈顶指针 */
	int stackSize; 				/* 当前已分配的存储空间,以元素为单位 */
} SqStack; 						/* 顺序栈 */

/* 构造一个空栈 S */
Status InitStack(SqStack *S);

/* 销毁栈 S */
void DestroyStack(SqStack *S);

/* 把 S 置为空栈 */
void ClearStack(SqStack *S);

/* 若栈 S 为空栈,则返回 TRUE,否则返回 FALSE */
Status StackEmpty(SqStack S);

/* 返回 S 的元素个数,即栈的长度 */
int StackLength(SqStack S);

/* 若栈不空,则用 e 返回 S 的栈顶元素,并返回 OK;否则返回 ERROR */
Status GetTop(SqStack S, SElemType *e);

/* 插入元素 e 为新的栈顶元素 */
Status Push(SqStack *S, SElemType e);

/* 若栈不空,则删除 S 的栈顶元素,用 e 返回其值,并返回 OK;否则返回 ERROR */
Status Pop(SqStack *S, SElemType *e);

/* 从栈底到栈顶依次对栈中每个元素调用函数 visit() */
void StackTraverse(SqStack S, void(*Visit)(SElemType));

#endif

5) sqStack.c

/* 栈的顺序存储表示源文件 */

#include "sqStack.h"
#include "status.h"
#include <stdlib.h>
#include <stdio.h>

/* 构造一个空栈 S */
Status InitStack(SqStack *S)
{
	(*S).base = (SElemType *)malloc(STACK_INIT_SIZE * sizeof(SElemType));
	if (!(*S).base) {
		printf("FuncName: %-15s Line: %-5d ErrorCode: %-3d\n", __func__, __LINE__, ERR_MEMORY_ALLOCATE);
		return ERR_MEMORY_ALLOCATE;
	}

	(*S).top = (*S).base;
	(*S).stackSize = STACK_INIT_SIZE;

	return RET_OK;
}

/* 销毁栈 S */
void DestroyStack(SqStack *S)
{
	free((*S).base);
	(*S).base = NULL;
	(*S).top = NULL;
	(*S).stackSize = 0;
}

/* 把 S 置为空栈 */
void ClearStack(SqStack *S)
{
	(*S).top = (*S).base;
}

/* 若栈 S 为空栈,则返回 TRUE,否则返回 FALSE */
Status StackEmpty(SqStack S)
{
	return (S.top == S.base) ? TRUE : FALSE;
}

/* 返回 S 的元素个数,即栈的长度 */
int StackLength(SqStack S)
{
	return (int)(S.top - S.base);
}

/* 若栈不空,则用 e 返回 S 的栈顶元素,并返回 OK;否则返回 ERROR */
Status GetTop(SqStack S, SElemType *e)
{
	if (S.top > S.base) {
		*e = *(S.top - 1);
		return RET_OK;
	}

	printf("FuncName: %-15s Line: %-5d ErrorCode: %-3d\n", __func__, __LINE__, ERR_NULL_STACK);

	return ERR_NULL_STACK;
}

/* 插入元素 e 为新的栈顶元素 */
Status Push(SqStack *S, SElemType e)
{
	if (((*S).top - (*S).base) == (*S).stackSize) {
		(*S).base = (SElemType *)realloc((*S).base, (unsigned long long)(((*S).stackSize) + STACKINCREMENT) * sizeof(SElemType));
		if (!(*S).base) {
			printf("FuncName: %-15s Line: %-5d ErrorCode: %-3d\n", __func__, __LINE__, ERR_MEMORY_ALLOCATE);
			return ERR_MEMORY_ALLOCATE;
		}

		(*S).top = (*S).base + (*S).stackSize;
		(*S).stackSize += STACKINCREMENT;
	}

	*((*S).top)++ = e;

	return RET_OK;
}

/* 若栈不空,则删除 S 的栈顶元素,用 e 返回其值,并返回 OK;否则返回 ERROR */
Status Pop(SqStack *S, SElemType *e)
{
	if ((*S).top == (*S).base) {
		printf("FuncName: %-15s Line: %-5d ErrorCode: %-3d\n", __func__, __LINE__, ERR_MEMORY_ALLOCATE);
		return ERR_MEMORY_ALLOCATE;
	}

	*e = *(--(*S).top);

	return RET_OK;
}

/* 从栈底到栈顶依次对栈中每个元素调用函数 visit() */
void StackTraverse(SqStack S, void(*Visit)(SElemType))
{
	while (S.top > S.base) {
		Visit(*S.base++);
	}
}

6) algorithm.h

/* 算法定义头文件 */
#ifndef ALGORITHM_H
#define ALGORITHM_H

#include "status.h"

/* 迷宫位置坐标 */
typedef struct {
	int x;
	int y;
} MazePosition;

#define D 8

#define MAXLENGTH 25			/* 设迷宫最大行列为 25 */

/* 定义墙元素值为 0,可通过路径为 -2, 不能通过路径为 -1 */
typedef int MazeType[MAXLENGTH][MAXLENGTH];

/* 利用非循环顺序队列采用广度搜索法求解迷宫问题, 求得第一条 路径,并返回 TRUE;否则返回 FALSE */
Status MazePath(const MazePosition start, const MazePosition end, MazeType *maze, int *totalStep);

/* 如果存在路径,输出求得的迷宫的解 */
void PrintMazePath(int row, int col, MazeType *maze);

#endif // !ALGORITHM_H

7) algorithm.c

/* 算法实现源文件 */

#include <windows.h>
#include "algorithm.h"
#include "sqStack.h"
#include "sqQueue.h"
#include <stdio.h>

/* 勿在头文件中定义,否则会重复包含 */
#if D == 4
	MazePosition direc[D] = { { -1, 0 }, { 1 , 0 }, { 0, -1 }, { 0, 1 } };
#endif

#if D == 8
	MazePosition direc[D] = { { -1, 0 }, { 1 , 0 }, { 0, -1 }, { 0, 1 },
		{ -1, -1 }, { -1, 1 }, { 1, -1 }, { 1, 1 } };
#endif

/*  定义墙元素值为 0,可通过路径为 -2, 不能通过路径为 -1, 通过路径为足迹
	当迷宫 maze 的 curPos 点的序号为 -2(可通过路径),return OK; 否则,return FALSE */
static Bollean PassPos(QElemType curPos, MazeType *maze)
{
	return ((*maze)[curPos.x][curPos.y] == -2) ? TRUE : FALSE;
}

/* 判断两个位置是否相同,相同返回 TRUE, 否则返回 FALSE */
static Bollean PostionSame(MazePosition pos1, QElemType pos2)
{
	return ((pos1.x == pos2.x) && (pos1.y == pos2.y)) ? TRUE : FALSE;
}

/* 利用非循环顺序队列采用广度搜索法求解迷宫问题, 求得第一条 路径,并返回 TRUE;否则返回 FALSE */
Status MazePath(MazePosition start, MazePosition end, MazeType *maze, int *totalStep)
{
	SqQueue Q;
	InitQueue(&Q);
	QElemType qECurr = { 0 };
	qECurr.preOrder = -1;
	qECurr.x = start.x;
	qECurr.y = start.y;
	(*maze)[qECurr.x][qECurr.y] = -1;
	EnQueue(qECurr, &Q);
	Bollean flag = FALSE;
	QElemType qENext = { 0 };
	while ((!QueueEmpty(&Q)) && (!flag)) {
		DeQueue(&Q, &qECurr);
		for (int i = 0; i < D; ++i) {
			qENext.x = qECurr.x + direc[i].x;
			qENext.y = qECurr.y + direc[i].y;
			if (PassPos(qENext, maze)) {
				(*maze)[qENext.x][qENext.y] = -1;
				qENext.preOrder = Q.front - 1;
				EnQueue(qENext, &Q);
				if (PostionSame(end, qENext)) {
					flag = TRUE;
					break;
				}
			}
		}
	}
		
	if (flag) {
		SqStack S;
		InitStack(&S);
		int pos = Q.rear - 1;
		while (pos >= 0) {
			SElemType sE = { Q.base[pos].x, Q.base[pos].y, Q.base[pos].preOrder };
			Push(&S, sE);
			pos = (Q.base[pos]).preOrder;
		}

		*totalStep = 0;
		SElemType sE;
		while (!StackEmpty(S)) {
			Pop(&S, &sE);
			++(*totalStep);
			(*maze)[sE.x][sE.y] = *totalStep;
		}

		return TRUE;
	}

	printf("No way!\n");

	return FALSE;
}

/* 设置字体颜色,入参为 0 - 15 */
static void SetColor(const unsigned short textColor)
{
	if ((textColor >= 0) && (textColor <= 15)) {
		SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), textColor);
	} else {
		SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 7);
	}
}

/* 如果存在路径,输出求得的迷宫的解 */
void PrintMazePath(int row, int col, MazeType *maze)
{
	for (int i = 0; i < row; ++i) {
		for (int j = 0; j < col; ++j) {
			if ((*maze)[i][j] > 0) {
				SetColor(2);
				printf("%3d", (*maze)[i][j]);
			} else {
				SetColor(7);
				printf("%3d", (*maze)[i][j]);
			}

		}

		printf("\n");
	}
}

8) main.c

/* 入口程序源文件 */

#include "algorithm.h"
#include <stdio.h>

int main(void)
{
	printf("Please input the row and col of the maze: ");
	int row = 0, col = 0;
	scanf_s("%d%d", &row, &col);
	MazeType maze = { 0 };
	for (int i = 0; i < col; ++i) {
		maze[0][i] = 0;
		maze[row - 1][i] = 0;
	}

	for (int i = 1; i < row - 1; ++i) {
		maze[i][0] = 0;
		maze[i][row - 1] = 0;
	}

	for (int i = 1; i < row - 1; ++i) {
		for (int j = 1; j < col - 1; ++j) {
			maze[i][j] = -2;
		}
	}

	printf("Please input the num of the wall: ");
	int wallNum = 0;
	scanf_s("%d", &wallNum);
	printf("Please input the position of the wall(x, y): \n");
	int x = 0, y = 0;
	for (int i = 0; i < wallNum; ++i) {
		scanf_s("%d%d", &x, &y);
		maze[x][y] = 0;
	}

	printf("The structure of the maze is:\n");
	PrintMazePath(row, col, &maze);
	MazePosition start = { 0 }, end = { 0 };
	printf("Please input the position of the start point(x, y):");
	scanf_s("%d%d", &start.x, &start.y);
	printf("Please input the position of the end point(x, y):");
	scanf_s("%d%d", &end.x, &end.y);
	int totalStep;
	if (MazePath(start, end, &maze, &totalStep)) {
		printf("\nUse %d steps, one of the path from start to end of the maze is:\n\n", totalStep);
		PrintMazePath(row, col, &maze);
	} else {
		printf("There is no way to the end.\n");
	}

	return 0;
}

3. 输出示例

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

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

相关文章

【JavaEE】_HTML

目录 1.HTML结构 2. HTML常用标签 2.1 注释标签 2.2 标题标签&#xff1a;h1~h6 2.3 段落标签&#xff1a;p 2.4 换行标签&#xff1a;br 2.5 格式化标签 2.6 图片标签&#xff1a;img 2.7 超链接标签&#xff1a;a 2.8 表格标签 2.9 列表标签 2.10 表单标签 2.10…

镜像的基本命令(docker)

文章目录 前言一、docker命令介绍1、帮助命令2、显示镜像3、搜索镜像4、下载镜像5、删除镜像 总结 前言 本文主要介绍docker中与镜像相关的一些命令&#xff0c;是对狂神课程的一些总结&#xff0c;作为一个手册帮助博主和使用docker的同学们来查找和回忆。 实验环境&#xf…

【Java 基础篇】深入理解 Java 中的抽象类:提高代码可维护性与扩展性

抽象类&#xff08;Abstract Class&#xff09;是 Java 面向对象编程中的一个重要概念。它允许我们定义一组抽象方法&#xff0c;这些方法可以被子类&#xff08;类&#xff09;实现。抽象类通常用于定义一些通用的方法和属性&#xff0c;但不能被实例化。本篇博客将深入探讨 J…

Java反序列化漏洞复现(weblogic和s2)

文章目录 weblogic启动环境漏洞扫描漏洞复现 S2-045启动环境漏洞复现 前提条件&#xff1a; 1.安装docker docker pull medicean/vulapps:j_joomla_22.安装docker-compose docker run -d -p 8000:80 medicean/vulapps:j_joomla_23.下载vulhub weblogic 启动环境 到下面路径下…

Mac13.4 (22F66)钥匙串无法导出.p12证书解决方案

最近更新了Mac 13.4系统之后&#xff0c;开发苹果APP项目时突然发现无法导出.p12证书 这情况解决方案如下方案 在钥匙串访问的上方&#xff0c;有一栏类型筛选&#xff0c;默认选中的是 “所有项目”&#xff0c;将选项切换至“证书” 切换到“证书”后&#xff0c;右键点击需要…

Ae 效果:CC Vector Blur

模糊和锐化/CC Vector Blur Blur & Sharpen/CC Vector Blur CC Vector Blur&#xff08;CC 向量模糊&#xff09;使用源图像&#xff08;图层自身或指定的向量映射图层&#xff09;的亮度差异或其他选择的属性&#xff08;如红通道、绿通道、蓝通道等&#xff09;来生成一个…

kafka学习-概念与简单实战

目录 1、核心概念 消息和批次 Topic和Partition Replicas Offset broker和集群 生产者和消费者 2、开发实战 2.1、消息发送 介绍 代码实现 2.2、消息消费 介绍 代码实现 2.3、SpringBoot Kafka pom application.yaml KafkaConfig producer consumer 1、核心…

【变分法】【书籍阅读笔记】Calculus of Variation by gelfand 第一章 总结与习题题解 【更新中】

文章目录 前言1 第一章 变分法基础1.1 泛函 与 一些简单的变分问题1.2 Function Spaces/ 赋范线性空间1.3 泛函的变分: 具有极值的必要条件1. 重要引理/线性泛函的等零条件2. 泛函变分 1.4 最简单的变分问题&#xff1a;欧拉方程1. 欧拉方程2. 证明/欧拉方程的得出3. 欧拉方程的…

机器学习:基于梯度下降算法的线性拟合实现和原理解析

机器学习&#xff1a;基于梯度下降算法的线性拟合实现和原理解析 线性拟合梯度下降算法步骤算法实现数据可视化&#xff08;动态展示&#xff09;应用示例 当我们需要寻找数据中的趋势、模式或关系时&#xff0c;线性拟合和梯度下降是两个强大的工具。这两个概念在统计学、机器…

SQLI-labs-第五关

知识点&#xff1a;布尔盲注 思路&#xff1a; 1、判断注入点 首先&#xff0c;我们看看正常的回显内容 ?id1 接着输入?id1 &#xff0c;结果出现语句错误 这里说明存在单引号的闭合错误 ?id1 and 11-- ?id1 and 12-- 这里没有任何回显信息&#xff0c;可以准确的确…

基于STM32程序万年历液晶1602显示-proteus仿真-源程序

一、系统方案 本设计采用STM32单片机作为主控器&#xff0c;液晶1602显示&#xff0c;按键设置万年历。 二、硬件设计 原理图如下&#xff1a; 三、单片机软件设计 1、首先是系统初始化 //通用定时器3中断初始化 //这里时钟选择为APB1的2倍&#xff0c;而APB1为36M //arr&…

官方YOLOV5的torch模型->ONNX模型->RKNN模型

1、环境配置 1.1 RKNN Toolkit2的环境配置 下载RKNN Toolkit2 git clone https://github.com/rockchip-linux/rknn-toolkit2.git打开一个终端命令行窗口,安装 Python3.6 和 pip3 sudo apt-get install python3 python3-dev python3-pip安装所需的依赖包 sudo apt-get inst…

机器学习笔记之最优化理论与方法(七)无约束优化问题——常用求解方法(上)

机器学习笔记之最优化理论与方法——基于无约束优化问题的常用求解方法[上] 引言总体介绍回顾&#xff1a;线搜索下降算法收敛速度的衡量方式线性收敛范围高阶收敛范围 二次终止性朴素算法&#xff1a;坐标轴交替下降法最速下降法(梯度下降法)梯度下降法的特点 针对最速下降法缺…

Vue + Element UI 前端篇(十二):用户管理模块

Vue Element UI 实现权限管理系统 前端篇&#xff08;十二&#xff09;&#xff1a;用户管理模块 用户管理模块 添加接口 在 http/moduls/user.js 中添加用户管理相关接口。 import axios from ../axios/* * 用户管理模块*/// 保存 export const save (params) > {ret…

Unity中Shader的变体shader_feature

文章目录 前言一、变体的类型1、multi_compile —— 无论如何都会被编译的变体2、shader_feature —— 通过材质的使用情况来决定是否编译的变体 二、使用 shader_feature 来控制 shader 效果的变化1、首先在属性面板暴露一个开关属性&#xff0c;用于配合shader_feature来控制…

解决deepspeed框架的bug:不保存调度器状态,模型训练重启时学习率从头开始

deepspeed存在一个bug&#xff0c;即在训练时不保存调度器状态&#xff0c;因此如果训练中断后再重新开始训练&#xff0c;调度器还是会从头开始而不是接着上一个checkpoint的调度器状态来训练。这个bug在deepspeed的github中也有其他人提出&#xff1a;https://github.com/mic…

清理Maven仓库中下载失败的文件

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页——&#x1f405;&#x1f43e;猫头虎的博客&#x1f390; &#x1f433; 《面试题大全专栏》 &#x1f995; 文章图文…

【SpringBoot】统一功能处理

目录 &#x1f383;1 拦截器 &#x1f380;1.1 拦截器的代码实现 &#x1f3a8;1.2 拦截器的实现原理 &#x1f9f6;2 拦截器应用——登录验证 &#x1f9ba;3 异常统一处理 &#x1f3ad;4 统一数据返回格式 &#x1f9e4;4.1 为什么需要统一数据返回格式 &#x1f9e3;4.2 统…

Cisco Packet Tracer入门篇

&#x1f490; &#x1f338; &#x1f337; &#x1f340; &#x1f339; &#x1f33b; &#x1f33a; &#x1f341; &#x1f343; &#x1f342; &#x1f33f; &#x1f344;&#x1f35d; &#x1f35b; &#x1f364; &#x1f4c3;个人主页 &#xff1a;阿然成长日记 …

Python中的文件I/O操作:常见问题与解决方案

在Python编程中&#xff0c;文件I/O操作是常见的任务。本文将介绍一些关于Python文件I/O操作的常见问题及其解决方案&#xff0c;并提供详细的代码示例。 1、问题&#xff1a;如何正确地打开和关闭文件&#xff1f; 解决方案&#xff1a;使用with语句可以确保文件在操作完成后…