手把手带你实现C语言扫雷进阶(1)(接上回基础版扫雷,附上源码)

news2024/11/15 11:02:23

文章目录

  • 一、扫雷进阶留下的问题
  • 二.非雷扩展周围不是雷函数
  • 三、标记雷函数
  • 四.查看排雷总时间
  • 五、扫雷进阶源码及总结

一、扫雷进阶留下的问题

我们先来看看之前讲扫雷基础的时候留下的一些问题:

  • 是否可以选择游戏难度
        ◦ 简单 9 * 9 棋盘,10个雷
        ◦ 中等 16 * 16棋盘,40个雷
        ◦ 困难 30 * 16棋盘,99个雷

  • 如果排查位置不是雷,周围也没有雷,可以展开周围的⼀⽚

  • 是否可以标记雷

  • 是否可以加上排雷总共耗费的时间

    要注意的一点是选择游戏难度以目前我们讲过的内容还暂时写不出来,在后面学习到相关内容时,我们再进行讲解,接下来就解决后三个问题
    我们的进阶还是在之前写过的基础版之上添加,如果还没有看过之前基础版,可以在我的主页查看,现在我们开始通过我们学过的知识解决这三个进阶需求

二.非雷扩展周围不是雷函数

    这个函数我们的目标就是实现:如果输入的坐标不是雷,那么查看周围是否有雷,如果至少有一个雷,那么就直接显示周围雷的个数,如果没有雷,把那个坐标换位字符’ ',也就是字符空格,而不再显示0,这样更加好看,随后向周围扩展,扩展到该坐标周围至少有一个雷时
    我们需要做一点更改,就是把输入的当前坐标,查看周围有几个雷放入这个函数,方便递归,现在可能有点懵,后面会慢慢解释
    这个函数实现起来有一定难度,必须要悟透递归的使用方法,同时还要注意数组越界等等问题,还要使用一点点超纲内容,就是指针,但是是最简单的指针内容,并且篇幅只有一点点,主要还是要体会循环递归的方式,以及递归的两个必要条件:

  • 递归存在限制条件,当满⾜这个限制条件的时候,递归便不再继续,如果没有限制,可能会陷入死递归
  • 每次递归调⽤之后越来越接近这个限制条件

接下来我们就进入这个函数的设计:

  1. 函数的命名:我将其命名为exdboard,exd是extend的缩写,含义是扩展,函数名就理解为扩展棋盘,也可自行命名

  2. 函数参数:
    (1)由于需要操作数组show和数组hide,所以要将这两个数组传过去
                                                                                                (2) 由于需要扩展周围的坐标,我们可以直接把当前坐标也一次性涵盖进去,就是先对当前坐标进行操作,查看周围是否有雷,如果没有雷就开始对周围坐标递归,所以我们需要传过去当前玩家输入的坐标,也就是x,y                                                                                           
    (3)然后由于我们要避免函数递归导致数组越界访问,所以我们要把行和列传过去,用来判断递归坐标的合法性                                                                                           
    (4)最后由于我们每递归一次,可能就会扩展一个坐标,而每扩展一次坐标我们需要win++一次,但是由于直接传win过去属于传值调用,在exdboard里面对win进行更改不会对真实的win产生影响,所以我们需要使用指针进行传址调用,这里听不懂没关系,后面会专门详细的为大家介绍指针,现在只需要跟着使用就行,并且在该函数它只有一个作用,那就是每次递归,如果扩展了一个坐标,就对win++一次,所以函数exdboard的最后一个参数是win的地址                                                                                           
    (5)所以函数exdboard的参数有:show和hide数组,玩家输入的坐标x,y,棋盘行和列,win的地址

  3. 函数的声明:我们要将函数设计好后,直接放在函数findboard中,所以可以直接在函数findboard上方进行实现,免去了在game.h里声明

  4. 函数的实现:
    (1)首先我们需要获取玩家输入的坐标位置周围雷的个数,如果没有雷的话,也就是show[x][y]==‘0’时,把这个位置改成字符空格,这样更加好看                                                                                           
    (2)执行完(1)的操作,相当于就是已经排查了一个坐标,我们要win++一次,如果还不了解指针的可以先照抄,学习后再来理解,反正在这里只用了很简单的指针知识,如下:

//指针变量int* ptr
//用来接收win传来的地址
//对它解引用就找到了win
(*ptr)++

    (3)随后我们开始思考该怎么递归,我们可以这样想,想要实现这个函数的功能,我们不能一口气直接完成,需要一步一步来,也就是把大事化小,如果当前坐标周围没有雷,我们可以以当前坐标为中心,进行扩展,一个一个找出周围的坐标,将它们当作新的中心进行扩展,如图:
在这里插入图片描述
    这样我们就将大问题化为了小问题,把扩展中心1周围的雷,化解为找多个中心,扩展它们周围的雷,形成递归,因为解决中心1和解决中心2的扩展是同类问题,方法相似,只要写出解决中心1的扩展,也就解决了其它中心的扩展,难点在于怎么找其它的中心呢?

    (4)我们可以定义一个i和j,表示新的中心的行和列,这时候我们可以用一个循环,找出中心1周围的坐标的行和列,然后将它们作为新的中心进行递归,如下:

for(i=x-1;i<=x+1;i++)
{
   for(j=y-1;j<=y+1;j++)
   {
      
   }
}

    这下我们就找出了坐标为x,y周围的所有坐标,可以将它们当作新的中心

    (5)我们现在开始思考整个递归的模型,我们说过递归一定要有尽头,有限制条件,每进行一次递归就要越来越靠近这个条件,我们可以称为递归的出口,经过思考,我们一定是要坐标周围没有雷,也就是show[x][y]!=‘ ’这个条件,如果这个条件满足,说明周围至少有一个雷,那么我们就可以返回了,不要递归下去了,由于每个中心的周围都只有8个坐标,再加上有雷的存在,所以迟早遇到某一个中心周围有雷,那么递归就开始返回了,不会死递归,如:

if (show[x][y]!=' ')
{
	return;
}

    (6)接下来思考从哪里开始递归,也就是递归的入口,经过前面的分析,很显而易见,我们要把递归的入口放在刚刚那个循环里面,这样构成了循环递归,将每一个周围的坐标作为中心,向周围扩展,但我们需要注意一些问题

  • 我们的递归不能让数组越界,也就是我们的新中心show[i][j],不能越界,必须满足
    i>=1 && i<=row && j>=1 && j<=col
  • 我们不能重复递归,比如2,4这个坐标已经做过中心了,如果递归递归着,2,4突然又做了中心,就重复递归了,就像使用递归求第n个斐波那契数一样,重复递归太多次导致效率太低,甚至低到我们不能接受,所以我们使用了循环,也就是迭代,那我们怎么避免重复递归呢?我们只需要判断一下show[i][j]是不是字符 *,如果是字符 ,说明这个坐标肯定还没有迭代过,可以放心迭代,所以我们可以再加一个条件show[i][j]=='',然后进入递归,如:
//循环递归:
for (i = x - 1; i <= x + 1; i++)
{
	for (j = y - 1; j <= y + 1; j++)
	{
		if(show[i][j] == '*' && i>=1 && i<=row && j>=1 && j<=col)
		{ 
			      //递归入口:
				exdboard(show, hide, i, j, row, col, ptr);
		}		
	}
}

    (7)经过我们的努力分析,现在我们基本上可以将这个函数构建出来了,参考代码如下:

//查看排查雷的那个坐标周围是否有雷,如果至少有一个雷就直接显示有几个雷
//如果周围没有雷,那么就对周围进行扩展
void exdboard(char show[Rows][Cols], char hide[Rows][Cols], int x,int y ,int row,int col, int* ptr)
{
	int i = 0;
	int j = 0;
	int ret = getcount(hide, x, y);
	show[x][y] = ret + '0';
	(*ptr)++;
	if (show[x][y] == '0')
	{
		show[x][y] = ' ';
	}
	
	//递归出口:
	if (show[x][y]!=' ')
	{
		return;
	}
	else
	{
		//循环递归:
		for (i = x - 1; i <= x + 1; i++)
		{
			for (j = y - 1; j <= y + 1; j++)
			{
				if(show[i][j] == '*' && i>=1 && i<=row && j>=1 && j<=col)
				{ 
					      //递归入口:
						exdboard(show, hide, i, j, row, col, ptr);
				}		
			}
		}
	}
}
  1. 函数的使用:我们可以直接放在排查雷函数中,如图:
    在这里插入图片描述

三、标记雷函数

    简单思路就是,每当玩家排查一次雷后,就询问是否要标记雷,如果回答是,那么就开始标记雷,回答否那么就继续排雷
    玩家要标记雷就是认为那个地方肯定不是雷,如果用一个通俗的符号表示否定,很容易就想到使用大写字母X,把它当做叉叉使用,所以实现标记雷就是把那个坐标位置的字符改为大写字符X,听上去就很容易实现,接下来我们仔细分析将其设计为一个函数:

  1. 函数命名:我命名为markmine,mark是标记,做记号的意思,mine有雷的意思,做一个参考,也可自行命名
  2. 函数参数: 由于我们需要更改展示给用户的数组show,所以我们需要把show数组传过去, 由于需要查看用户输入的坐标是否合法,所以要把实际棋盘大小的行和列,也就是Row和Col传过去。所以函数参数有show数组、Row和Col
  3. 函数声明:我们可以思考一下,我们设计的函数markmine,他的作用是玩家排查雷后,然后询问是否标记雷,回答是后,再进行标记,我们可以这样,将函数markmine直接放入函数findboard的最后,然后在findboard上方实现,这样就不用再gam.h中专门声明了
  4. 函数实现:现在我们按点来分析一下总体思路
    (1)在排查完一次雷后,进入函数询问玩家是否标记雷,然后让用户输入一个值,用来给我们判断,输入是就标记雷,输入否就不标记                                                                                           
    (2)由于要比较两个字符串是否相等,不能直接用==,要使用strcmp,并且在game.h声明头文件string.h,如果strcmp返回值是0,那么两个字符串相等,反之就不相等                                                                                           
    (3)有时玩家可能需要标记多个雷,所以我们可以在玩家输入是后再次询问,需要标记几个雷,并且给予提示,还需要标记多少个雷                                                                                           
    (4)我们可以使用变量num来接收玩家输入的数量,然后将其作为while的循环条件,每标记一次雷,num–,到最后num为0时循环就自动结束了                                                                                           
    (5)为了防止用户输入的坐标越界,我们需要对用户输入的坐标进行判断,必须满足棋盘大小                                                                                           
    (6)为了防止用户不小心输入已经排除的位置,比如坐标6,5已经知道不是雷了,用户却不小心输入错误,标记成雷了,我们可以加一个限制条件,就是show[x][y]的位置必须是字符*,也就保证了标记的位置不会是已经排除的位置                                                                                           
    (7)最后一步就很简单了,只需要将用户输入坐标的位置改成大写字母‘X’                                                                                           
    (8)代码如下:
//实现标记雷函数:
void markmine(char show[Rows][Cols], int row, int col)
{
	int x = 0;
	int y = 0;
	int i = 0;
	int num = 0;
	char arr[10] = { 0 };
	printf("\n*****是否标记雷*****:");
	scanf("%s",arr);
	if (strcmp(arr, "是") == 0)
	{
		printf("\n***请输入要标记的雷的个数***:");
		scanf("%d", &num);
		while (num)
		{
			printf("\n请输入要标记的雷的坐标,还需要标记%d个雷:",num);
			scanf("%d %d", &x, &y);
			if (show[x][y]=='*' && x >= 1 && x <= row && y >= 1 && y <= col)
			{
				show[x][y] = 'X';
				num--;
			}
			else
			{
				printf("输入不合法,请重新输入!\n");
			}
			
		}
	}
	else
	{
		printf("\n");
	}
}

  1. 函数运用:最后运用函数时记得将其放在排查雷函数后,如图:
    在这里插入图片描述

四.查看排雷总时间

    从原理上这个问题很好解决,就是游戏结束的时间减去游戏开始的时间,要解决这样一个问题我们就要重新回顾一下time函数
    当time函数的参数为NULL时,它会返回一个时间戳,就是从1970年1月1日0时0分0秒到现在这个时间有多少秒,返回类型是time_t,本质上是一个32位或者64位的整型,可以使用占位符%td打印它
    如果我们要算游戏总共花费多少时间,我们可以直接在游戏开始时,在game函数最上面创建一个变量start来接收游戏开始时,在game函数最下面,也就是游戏结束时创建一个变量end来接收结束时的时间戳,然后将它们相减即可
    为了方便,我们可以显示精确到秒的时间,同时显示大约多少分钟,分钟就用秒数除以60即可,代码如下:

void game()
{
	//游戏开始的时间戳
	time_t start = time(NULL);

	//不显示出来,用于布置雷
	char hide[Rows][Cols];

	//显示出来,用于排查雷
	char show[Rows][Cols];

	//初始化棋盘:
	initboard(hide, Rows, Cols, '0');
	initboard(show, Rows, Cols, '*');

	//布置雷:
	setboard(hide, Count);

	//打印棋盘:
	printboard(show, Row, Col);
	printboard(hide, Row, Col);

	//排查雷:
	findboard(show, hide, Row, Col, Count);

	//游戏结束时的时间戳
	time_t end = time(NULL);
	printf("共花费%td秒,大约%td分钟\n\n",end-start,(end-start)/60);
}

五、扫雷进阶源码及总结

game.h

#pragma once

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>

//显示的棋盘大小
#define Row 9
#define Col 9

//实际的棋盘大小
#define Rows Row+2
#define Cols Col+2

//雷的个数:
#define Count 10

//声明初始化棋盘函数:
void initboard(char board[Rows][Cols], int rows, int cols, char x);

//声明打印棋盘函数:
void printboard(char board[Rows][Cols], int row, int col);

//声明布置雷函数:
void setboard(char board[Rows][Cols], int count);

//声明排查雷函数
void findboard(char show[Rows][Cols], char hide[Rows][Cols], int row, int col, int count);

game.c

#define _CRT_SECURE_NO_WARNINGS

#define _CRT_SECURE_NO_WARNINGS

#include "game.h"

//实现初始化棋盘函数:
void initboard(char board[Rows][Cols], int rows, int cols, char x)
{
	int i = 0;
	int j = 0;
	for (i = 0; i < rows; i++)
	{
		for (j = 0; j < cols; j++)
		{
			board[i][j] = x;
		}
	}
}

//实现打印棋盘函数:
void printboard(char board[Rows][Cols], int row, int col)
{
	int i = 1;
	int j = 1;
	//打印棋盘标志,让棋盘更显眼
	printf("------ 扫雷 -------\n");
	//打印列号:
	for (i = 0; i <= col; i++)
	{
		printf("%d ", i);
	}
	//列号打印完进行换行
	printf("\n");

	for (i = 1; i <= row; i++)
	{
		//打印行号
		printf("%d ", i);
		for (j = 1; j <= col; j++)
		{
			printf("%c ", board[i][j]);
		}
		//每打印完一行就要进行一次换行:
		printf("\n");
	}
	//打印棋盘标志,让棋盘更显眼
	printf("------ 扫雷 -------\n");
	//棋盘打印完之后进行换行
	printf("\n");
}

//实现布置雷函数:
void setboard(char board[Rows][Cols], int count)
{
	while (count)
	{
		int x = rand() % Row + 1;
		int y = rand() % Col + 1;
		if (board[x][y] != '1')
		{
			board[x][y] = '1';
			count--;
		}
	}
}

//如果坐标不是雷,获取坐标周围雷的个数
int getcount(char hide[Rows][Cols], int x, int y)
{
	return (hide[x][y - 1] + hide[x][y + 1] +
		hide[x - 1][y] + hide[x - 1][y - 1] + hide[x - 1][y + 1] +
		hide[x + 1][y] + hide[x + 1][y - 1] + hide[x + 1][y + 1] - 8 * '0');
}

//查看排查雷的那个坐标周围是否有雷,如果至少有一个雷就直接显示有几个雷
//如果周围没有雷,那么就对周围进行扩展
void exdboard(char show[Rows][Cols], char hide[Rows][Cols], int x,int y ,int row,int col, int* ptr)
{
	int i = 0;
	int j = 0;
	int ret = getcount(hide, x, y);
	show[x][y] = ret + '0';
	(*ptr)++;
	if (show[x][y] == '0')
	{
		show[x][y] = ' ';
	}
	
	//递归出口:
	if (show[x][y]!=' ')
	{
		return;
	}
	else
	{
		//循环递归:
		for (i = x - 1; i <= x + 1; i++)
		{
			for (j = y - 1; j <= y + 1; j++)
			{
				if(show[i][j] == '*' && i>=1 && i<=row && j>=1 && j<=col)
				{ 
					      //递归入口:
						exdboard(show, hide, i, j, row, col, ptr);
				}		
			}
		}
	}

}

//实现标记雷函数:
void markmine(char show[Rows][Cols], int row, int col)
{
	int x = 0;
	int y = 0;
	int i = 0;
	int num = 0;
	char arr[10] = { 0 };
	printf("\n*****是否标记雷*****:");
	scanf("%s",arr);
	if (strcmp(arr, "是") == 0)
	{
		printf("\n***请输入要标记的雷的个数***:");
		scanf("%d", &num);
		while (num)
		{
			printf("\n请输入要标记的雷的坐标,还需要标记%d个雷:",num);
			scanf("%d %d", &x, &y);
			if (show[x][y]=='*' && x >= 1 && x <= row && y >= 1 && y <= col)
			{
				show[x][y] = 'X';
				num--;
			}
			else
			{
				printf("输入不合法,请重新输入!\n");
			}
			
		}
	}
	else
	{
		printf("\n");
	}
}

//实现排查雷函数:
void findboard(char show[Rows][Cols], char hide[Rows][Cols], int row, int col, int count)
{
	int x = 0;
	int y = 0;
	int win = 0;
	printf("请输入英文逗号隔开坐标!\n\n");
	while (win < Row * Col - Count)
	{
		printf("请输入要排查的坐标:");
		//这里需要用到之前学过的%*c,就是
		//scanf的赋值忽略符*
		//使用过后就可以输入空格或者英文逗号隔开坐标,最好英文逗号
		//但是不能用中文
		//这里中文和英文逗号不能都使用
		//所以我们最好在开始时给予一些提示
		scanf("%d%*c%d", &x, &y);
		printf("\n");
		if (x >= 1 && x <= row && y >= 1 && y <= col)
		{
			if (hide[x][y] == '1')
			{
				printf("很遗憾,你踩到雷了,游戏失败!\n\n");
				printf("显示的0代表不是雷,1表示雷\n\n");
				printboard(hide, Row, Col);
				break;
			}
			else
			{
				//扩展棋盘:
				exdboard(show, hide,x,y, row, col, &win);
				printboard(show, Row, Col);

				//标记雷
				markmine(show, row, col);
				printboard(show, Row, Col);
			}
		}
		else
		{
			printf("输入不合法,请重新输入!\n");
		}
	}
	if (win == Row * Col - Count)
	{
		printf("恭喜你,扫雷成功!\n\n");
		printf("显示的0代表不是雷,1表示雷\n\n");
		printboard(hide, Row, Col);
	}
}

test.c

#define _CRT_SECURE_NO_WARNINGS

#define _CRT_SECURE_NO_WARNINGS

#include "game.h"

void menu()
{
	printf("********************\n");
	printf("**** 1.开始游戏 ****\n");
	printf("**** 0.退出游戏 ****\n");
	printf("********************\n\n");
	printf("提示:请输入1或0\n");
}


void game()
{
	//游戏开始的时间戳
	time_t start = time(NULL);

	//不显示出来,用于布置雷
	char hide[Rows][Cols];

	//显示出来,用于排查雷
	char show[Rows][Cols];

	//初始化棋盘:
	initboard(hide, Rows, Cols, '0');
	initboard(show, Rows, Cols, '*');

	//布置雷:
	setboard(hide, Count);

	//打印棋盘:
	printboard(show, Row, Col);
	//printboard(hide, Row, Col);

	//排查雷:
	findboard(show, hide, Row, Col, Count);

	//游戏结束时的时间戳
	time_t end = time(NULL);
	printf("共花费%td秒,大约%td分钟\n\n",end-start,(end-start)/60);
}


int main()
{
	srand((unsigned int)time(NULL));
	int input = 0;
	do
	{
		menu();
		printf("\n请选择:");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			game();
			break;
		case 0:
			printf("游戏退出成功\n");
			break;
		default:
			printf("\n选择错误,请重新输入!\n\n");
			break;
		}
	} while (input);
	return 0;
}

    本文内容偏难,如果有疑问欢迎在评论区提问,一定会及时答复
    对于扫雷进阶(2)也就是最后一点内容:选择游戏难度,我会在后面讲到相关知识点后出一篇文,希望不要被当前这个扫雷进阶(1)难到而放弃,继续往后面学习,你就会发现它很简单,在扫雷进阶(2)的时候是否会觉得扫雷进阶(1)很简单呢?我们拭目以待吧!

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

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

相关文章

【Qt】Qt 网络 | UDP Socket

文章目录 核心API代码示例服务器客户端 要使用 Qt 网络编程&#xff0c;需要在项目中的 .pro 文件中添加 network 模块 核心API Qt 的 UDP Socket 主要的类有两个 QUdpSocket 和 QNetworkDatagram 因为是 UDP 是面向数据报的&#xff0c;QNetworkDatagram 就是对 数据报的封…

【项目管理】系统设计与开发管理规程(Word完整文件)

2 过程总体描述 2.1 过程概述 2.2 过程流程图 3 过程元素描述 3.1 产品方案 3.2 产品设计 3.3 产品实现 获取方式&#xff1a;本文末个人名片直接获取。 软件资料清单列表部分文档清单&#xff1a;工作安排任务书&#xff0c;可行性分析报告&#xff0c;立项申请审批表&#xf…

【模拟器-夜神】Mac卡在99%问题

▒ 目录 ▒ &#x1f6eb; 导读需求 1️⃣ 首次启动提示2️⃣ 手动授权允许加载驱动非苹果CPU苹果CPU &#x1f4d6; 参考资料 &#x1f6eb; 导读 需求 解决模拟器中遇到的问题 &#xff0c;汇总。 1️⃣ 首次启动提示 首次点击图标启动时会弹出提示&#xff1a; 解决方式如…

本地搭建XSS 漏洞接收平台实践分享

免责声明 本文仅限于学习讨论与技术知识的分享&#xff0c;不得违反当地国家的法律法规。对于传播、利用文章中提供的信息而造成的任何直接或者间接的后果及损失&#xff0c;均由使用者本人负责&#xff0c;本文作者不为此承担任何责任&#xff0c;一旦造成后果请自行承担&…

操作系统面试真题总结(二)

文章收录在网站&#xff1a;http://hardyfish.top/ 文章收录在网站&#xff1a;http://hardyfish.top/ 文章收录在网站&#xff1a;http://hardyfish.top/ 文章收录在网站&#xff1a;http://hardyfish.top/ 栈空间和空间堆有什么区别&#xff1f;各自优缺点呢&#xff1f; …

diffusion 模型gguf量化使用案例,支持CPU运行

参考: https://github.com/leejet/stable-diffusion.cpp 在线demo使用: https://colab.research.google.com/drive/1NkAzSn3iYOwkY1Jy7qJfV_d2ZMHQmXrK?usp=sharing 一般gguf量化质量 fp16 > Q8 > fp8 > Q4 > Q4k_m > Q4k_s > nf4 安装 !git clone --r…

[H贪心] lc3273. 对 Bob 造成的最少伤害(贪心+排序+推公式+双周赛138_4)

文章目录 1. 题目来源2. 题目解析 1. 题目来源 链接&#xff1a;3273. 对 Bob 造成的最少伤害 题单&#xff1a; na na 2. 题目解析 略低于正常难度的 T4。 显然我们应该尽可能的将伤害高的先消掉&#xff0c;然后写完代码就会发现 WA 了。想太简单了&#xff0c;那就推…

如何在JPG文件中隐写数据

概述 最近在做资源管理器背景的一个功能时&#xff0c;需要将信息传递到DLL中去&#xff0c; 主要就是传递一些比较简单的参数&#xff0c;包括图片的契合度&#xff0c;透明度之类的。通信方式有多种&#xff0c;毕竟是练手的功能&#xff0c;就想找一些以前没用过的方式。 …

心觉:潜意识精准显化(一)开篇

Hi&#xff0c;我是心觉&#xff0c;与你一起玩转潜意识、脑波音乐和吸引力法则&#xff0c;轻松搞定人生挑战&#xff0c;实现心中梦想&#xff01; 挑战日更写作156/1000(完整记录在下面) 公门洞开纳百川 众心逐梦越千山 号召引领潜力绽 心觉潜意识无间 每个人都渴望自…

psql常见报错解决

问题 解决 要在管理员模式下启动 pg_ctl start -D "D:\Program\PostgreSQL\data" 注册成服务 D:\Program\PostgreSQL\bin\pg_ctl.exe register -N "postgresql" -D "D:\Program\PostgreSQL\data" -U "postgres" -P "postgre…

华为 HCIP-Datacom H12-821 题库 (1)

有需要题库的可以看主页置顶 1.MSTP 有不同的端口角色&#xff0c;对此说法不正确的是&#xff1a; A、MSTP 中除边缘端口外&#xff0c;其他端口角色都参与 MSTP 的计算过程 B、MSTP 同一端口在不同的生成树实例中可以担任不同的角色。 C、MSTP 域边缘端口是指位于 MST 域的边…

桶排序【算法 14】

桶排序算法详解 桶排序&#xff08;Bucket Sort&#xff09;是一种基于分配的排序算法&#xff0c;适用于均匀分布在特定范围内的数据。其核心思想是将输入数据分到若干个桶&#xff08;Bucket&#xff09;中&#xff0c;每个桶分别进行排序&#xff0c;最后合并桶内的元素形成…

【STM32】BKP备份寄存器与RTC实时时钟

本篇博客重点在于标准库函数的理解与使用&#xff0c;搭建一个框架便于快速开发 目录 BKP简介 BKP代码注解 读写备份寄存器 复位备份寄存器 BKP代码 RTC简介 RTC代码注解 RTCCLK时钟源选择 分频器配置 时钟同步 RTC代码 MyRTC.h MyRTC.c main.c BKP简介 BKP&…

TeamTalk路由服务器

路由相关信令和协议设计 enum BuddyListCmdID {// ...... 暂时省略无关信令CID_BUDDY_LIST_USERS_STATUS_REQUEST 522,CID_BUDDY_LIST_USERS_STATUS_RESPONSE 523,// ...... 暂时省略无关信令 };message IMUsersStatReq{//cmd id: 0x020arequired uint32 user_id 1;repeat…

JS设计模式之“名片设计师” - 工厂方法模式

image.png 前言 上篇文章我们了解到什么是简单工厂模式&#xff0c;请参考上篇文章&#xff1a;JS设计模式之 “神奇的魔术师” - 简单工厂模式&#xff0c;不过这是工厂中最简单的一种&#xff0c;本篇文章我们将同大家一起认识一种更复杂的工厂模式&#xff0c;它将给我们提…

【Kubernetes】声明式创建各种资源

k8s声明式创建 kubernetes陈述式创建与声明式创建yaml各个字段含义Pod yaml文件详解deployment.yaml文件详解server.yaml文件详解 k8s中port的区别1、声明式创建pod label包含app: zhangsan2、声明式创建deployment&#xff0c;包含3个nginx副本&#xff0c;label包含app: zhan…

【MyBatis】MyBatis的一级缓存和二级缓存简介

目录 1、一级缓存 1.1 我们在一个 sqlSession 中&#xff0c;对 User 表根据id进行两次查询&#xff0c;查看他们发出sql语句的情况。 1.2 同样是对user表进行两次查询&#xff0c;只不过两次查询之间进行了一次update操作。 1.3 一级缓存查询过程 1.4 Mybatis与Spring整…

Windows10上安装PostgreSQL 16

PostgreSQL是一个先进的、开源的、免费的、功能强大的关系型数据库&#xff0c;它使用并扩展了SQL语言&#xff0c;并结合了许多功能&#xff0c;可以安全地存储和扩展复杂的数据工作负载。PostgreSQL可在Windows、Linux、macOS等多个平台上运行&#xff0c;License使用Postgre…

hive学习(五)

一、hive的DML操作 1.load&#xff08;向表中装载数据&#xff09; hive> load data [local] inpath 路径 [overwrite] into table 表名 [partition (partcol1val1,…)];特殊说明 1&#xff09;local&#xff1a;标识从本地加载数据到Hive表&#xff0c;若没有local的话从…

Linux系统下KubeSphere3.4.1离线安装包制作及部署过程

一、概述 KubeSphere 是 GitHub 上的一个开源项目&#xff0c;是成千上万名社区用户的聚集地。很多用户都在使用 KubeSphere 运行工作负载。对于在 Linux 上的安装&#xff0c;KubeSphere 既可以部署在云端&#xff0c;也可以部署在本地环境中&#xff0c;例如 AWS EC2、Azure…