三子棋游戏的实现

news2024/10/6 16:18:57

        前言:相信大家都玩过三子棋吧,曾想经常和同学在考试之后玩一个晚自习的三子棋。那么,如何自己编写一个三子棋游戏呢,请看下面的分析;

1.游戏设计思路

        在写任何代码时,最好先有个大致的框架,然后在大的框架下不断填充相应的细节,来实现相应的功能。

那么,想设计一个三子棋游戏需要哪些步骤呢

            1.主函数部分

            2.初始化棋盘

            3.打印棋盘

            4.下棋(玩家和电脑)

            5.判断输赢

2.设计之前的一些准备

        可以预见到,在编写游戏时需要使用到大量的函数,如果在同一文件下既声明函数,又定义函数,最后再调用函数,会使得整个程序杂乱无章,难以阅读。这时,利用分模块编程的方法就可以很好的避免代码混乱,冗长的问题。

        所谓分模块编程,即创立三个文件,一个头文件game.h(用来存放函数的声明,包括各种库函数以及使用到的标识符常量),两个源文件game.c(用来存放函数的定义)和test.c(函数的实现以及主函数);

        同时,为了使代码的灵活性大大提高,我们可以使用#define 定义的标识符常量来定义棋盘的大小;

3.具体实现过程

        1.主函数部分

                主函数是整个游戏过程的初始化,要根据用户的要求来判断是否进行游戏;

                代码如下:

int main()
{
	srand((unsigned int)time(NULL));
	int input = 0;
	do            //不管三七二十一先打印一次菜单              
	{
		menu();//打印菜单
		scanf("%d",&input);
		//根据用户输入的内容来判断是否进行后续操作
		switch (input)
		{
			case 1:
				game();
				break;
			case 0:
				printf("退出游戏\n");
				break;
			default:
				printf("输入错误,请重新输入");
		}
	} while (input); //只有输入0的时候才会推出循环(0为假)
	return 0;
}

        2.初始化棋盘

                分析:棋盘是用来落子的,在程序中其实就是存放数据的,又因为棋盘的形状,很自然的想到使用二维数组存放数据,所以我们可以使用二维数组来初始化棋盘

//game.h      //函数声明,定义都要指明各参数的类型
void InitBoard (char board [ROW][COL], int row, int col);

//game.c
void InitBoard(char board[ROW][COL], int row, int col)
{
	int i = 0;
	int j = 0;
	for (i = 0; i < row; i++)
	{
		for (j = 0; j < col; j++)
		{
			board[i][j] = ' ';//将棋盘全部初始化为空格
		}                     //注意这里不是"",是'',因为空格本质上是个字符,引用字符要使用单引号
	}                         //若使用" ",本质上是一个字符串引用,实际上存储了两个字符,还有\0
}

//1.test.c  存放数据 ->二维数组      先用空格代替
	InitBoard(board, ROW, COL);

        3.打印棋盘

                在初始化棋盘后,发现棋盘仅仅只能存储数据(而且数据是空格),并没有边界线,所以我们要想办法打印棋盘

#define ROW 3      //这个刚开始犯了一个巨低级的错误,在最后添加了;
#define COL 3      //只有语句的结束才需要添加分号

//game.h
//打印棋盘
void DisplayBoard(char board[ROW][COL], int row, int col);

//game.c
//打印棋盘

//版本1    只有空格  并没有分割线,不符合棋盘样式
//void DisplayBoard(char board[ROW][COL], int row, int col)
//{
//	int i = 0;
//	int j = 0;
//	for (i = 0; i < row; i++)
//	{
//		for (j = 0; j < col; j++)
//		{
//			printf("%c", board[i][j]);
//		}
//		printf("\n");
//	}
//}

//版本2      行数和列数都限制死了
//void DisplayBoard(char board[ROW][COL], int row, int col)
//{
//	int i = 0;
//	//一行一行打印
//	for (i = 0; i < row; i++)
//	{
//	//1.打印数据
//		printf(" %c | %c | %c \n", board[i][0], board[i][1], board[i][2]);
//	//2.打印分割线
//		if(i<row -1 )//最后一行不打印分割线
//			printf("---|---|---\n");
//	}
//
//}

//版本3       利用大事化小的思维,利用循环打印数据和分割线
void DisplayBoard(char board[ROW][COL], int row, int col)
{
	int i = 0;
	//一行一行打印
	for (i = 0; i < row; i++)
	{
		int j = 0;
		//拆分为更小的单位
		for (j = 0; j < col; j++)
		{
			//打印数据
			printf(" %c ",board[i][j]);

			if (j < col - 1)//最后一个|不打印
			{
				printf("|");
			}
		}
		printf("\n");
		//打分割线
		if (i < row - 1)
		{
			int j = 0;
			for (j = 0; j < col; j++)//有几列就有几组
			{
				printf("---");
				if (j < col - 1)
				{
					printf("|");
				}
			}
			printf("\n");
		}
	}
}

//test.c
//2.打印棋盘
	DisplayBoard(board, ROW, COL);

        4.模拟下棋(玩家and电脑)

                下棋整个过程是游戏实现的重要步骤,在下棋的过程中要模拟真实世界的下棋过程(循环一直对垒,直到分出输赢),下面请看代码实现

game.h

//下棋
//玩家下棋
void PlayerMove(char board[ROW][COL], int row, int col);
	
//电脑下棋
void ComMove(char board[ROW][COL], int row, int col);

game.c

//下棋
//玩家先步
void PlayerMove(char board[ROW][COL], int row, int col)
{
	//给用户提供坐标
	int x = 0;
	int y = 0;
	printf("玩家下棋->");
	while (1)
	{
		printf("请输入要下的坐标,中间请用空格分隔->\n");
		scanf("%d %d", &x, &y);//用户输入之后,要判断用户输入的行数和列数是否合法
		if (x >= 1 && x <= row && y >= 1 && y <= col)//输入合法
		{
			//要注意从用户的角度去思考,用户只认为的第一行是从1开始的,而不是0
			if (board[x - 1][y - 1] == ' ')//分两种情况讨论
			{                              //1.位置没有被占用
				board[x - 1][y - 1] = '*';
				break;//输入正确就挑出玩家下棋的过程
			}
			else                           //2.位置已被占用
			{
				printf("该位置已被占用,请重新输入");
			}
		}
		else   //也要考虑到玩家有可能输入的坐标值越界
		{
			printf("坐标非法,请重新输入:");
		}
	}
}

//电脑下棋
void ComMove(char board[ROW][COL], int row, int col)//可见,电脑和用户还是有很大区别的
{
	int x = 0;
	int y = 0;
	printf("电脑下棋->\n");
	//电脑下的位置是随机的  但是也要满足下棋的规则
	while (1)
	{
		x = rand() % row;//产生0-row-1的随机数
		y = rand() % col;
		if ( board[x][y] ==' ')
		{
			board[x][y] = '#';
			break;
		}
	}
	
}


test.c

while (1)//用循环模拟对战环节    下一步棋,打印一次
	{
		PlayerMove(board, ROW, COL);//玩家下棋
		DisplayBoard(board, ROW, COL);}

        5.判断输赢

                在每一次玩家或者电脑落子之后都要进行一次输赢的判断;这里的难点在于要对输赢的条件进行充分的考虑。比赛的结果分为三种,玩家赢,电脑赢,平局;

                比如获胜的情况大致可分为四种,主对角线,次对角线,横着一排,竖着一排,每种情况都要设置相应的代码;

下面请看代码实现过程

game.h

//判断输赢  在玩家或者用户每一次落子之后进行判断
//玩家赢  '*'
//电脑赢  '#'
//平局    'Q'//这样设置返回值的原因是:除了继续这种条件外,其他的都属于游戏结束的范畴
//继续    'C' //那我只需接受返回值,不是c,就跳出对垒,游戏结束        

int IsWin(char board[ROW][COL], int row, int col);


game.c

int IsFull(char board[ROW][COL], int row, int col)
{
	int i = 0;
	int j = 0;
	for (i = 0; i < row; i++)
	{
		for (j = 0; j < col; j++)
		{
			if (board[i][j] == ' ')
				return 0;
		}
	}
	return 1;//找不到空格,证明满了,就是平局
}

int IsWin(char board[ROW][COL], int row, int col)
{
	//先判断赢
	//1.连成一行
	int i = 0;
	for (i = 0; i < row; i++)
	{
		if (board[i][0] == board[i][1] && board[i][1] == board[i][2] &&board[i][0]!=' ')
			return board[i][0];
	}
	//2.连成一列
	int j = 0;
	for (j = 0; j < col; j++)
	{
		if (board[0][j] == board[1][j] && board[1][j] == board[2][j] && board[0][j]!=' ')
			return board[0][j];
	}
	//3.对角线
	//主对角线
	if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[0][0]!=' ')
		return board[0][0];
	//次对角线
	if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[0][2]!=' ')
		return board[0][2];

	//平局
	if (IsFull(board,row,col) == 1)
		return 'Q';
	//继续
	return 'C';
}



test.c
while (1)//用循环模拟对战环节    下一步棋,打印一次
	{
		PlayerMove(board, ROW, COL);//玩家下棋
		DisplayBoard(board, ROW, COL);
		//判断输赢
		ret = IsWin(board, ROW, COL);
		if (ret != 'C')
			break;

		ComMove(board, ROW, COL);
		DisplayBoard(board, ROW, COL);
		//判断输赢
        ret = IsWin(board, ROW, COL);
		if (ret != 'C') //只要不是c继续这种条件,其余情况都属于游戏结束的范畴
			break;
	}
	if (ret == '*')
		printf("玩家赢\n");
	else if (ret == '#')
		printf("电脑赢\n");
	else
		printf("平局\n");
	
}


4.总结部分

        通过编写三子棋游戏,很锻炼我们的思维,我们不能仅仅认为代码能跑就行,而是应该不断去优化我们的代码,这样我们的代码能力才可以提高。在编写代码时,我们要有自己的大致框架,路线是个纲,沿着正确的路线不断填充我们的细节;

最后附上各文件完整程序代码

game.h

#pragma once
//此文件是与游戏有关函数声明部分 
//有一个细节,将所有的可能用到的头文件都写到game.h之中,在其余的文件中只需引用此文件即可
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define ROW 3      //这个刚开始犯了一个巨低级的错误,在最后添加了;
#define COL 3      //只有语句的结束才需要添加分号
//这样定义的好处可以自由改变棋盘的大小



//初始化棋盘       //函数声明,定义都要指明各参数的类型
void InitBoard (char board [ROW][COL], int row, int col);

//打印棋盘
void DisplayBoard(char board[ROW][COL], int row, int col);

//下棋
//玩家下棋
void PlayerMove(char board[ROW][COL], int row, int col);
	
//电脑下棋
void ComMove(char board[ROW][COL], int row, int col);

//判断输赢  在玩家或者用户每一次落子之后进行判断
//玩家赢  '*'
//电脑赢  '#'
//平局    'Q'//这样设置返回值的原因是:除了继续这种条件外,其他的都属于游戏结束的范畴
//继续    'C' //那我只需接受返回值,不是c,就跳出对垒,游戏结束        

int IsWin(char board[ROW][COL], int row, int col);

game.c

//此文件是和游戏有关函数的定义部分
#define _CRT_SECURE_NO_WARNINGS 1
#include "game.h"

//初始化棋盘
void InitBoard(char board[ROW][COL], int row, int col)
{
	int i = 0;
	int j = 0;
	for (i = 0; i < row; i++)
	{
		for (j = 0; j < col; j++)
		{
			board[i][j] = ' ';//将棋盘全部初始化为空格
		}                     //注意这里不是"",是'',因为空格本质上是个字符,引用字符要使用单引号
	}                         //若使用" ",本质上是一个字符串引用,实际上存储了两个字符,还有\0
}

//打印棋盘

//版本1    只有空格  并没有分割线,不符合棋盘样式
//void DisplayBoard(char board[ROW][COL], int row, int col)
//{
//	int i = 0;
//	int j = 0;
//	for (i = 0; i < row; i++)
//	{
//		for (j = 0; j < col; j++)
//		{
//			printf("%c", board[i][j]);
//		}
//		printf("\n");
//	}
//}

//版本2      行数和列数都限制死了
//void DisplayBoard(char board[ROW][COL], int row, int col)
//{
//	int i = 0;
//	//一行一行打印
//	for (i = 0; i < row; i++)
//	{
//	//1.打印数据
//		printf(" %c | %c | %c \n", board[i][0], board[i][1], board[i][2]);
//	//2.打印分割线
//		if(i<row -1 )//最后一行不打印分割线
//			printf("---|---|---\n");
//	}
//
//}

//版本3       利用大事化小的思维,利用循环打印数据和分割线
void DisplayBoard(char board[ROW][COL], int row, int col)
{
	int i = 0;
	//一行一行打印
	for (i = 0; i < row; i++)
	{
		int j = 0;
		//拆分为更小的单位
		for (j = 0; j < col; j++)
		{
			//打印数据
			printf(" %c ",board[i][j]);

			if (j < col - 1)//最后一个|不打印
			{
				printf("|");
			}
		}
		printf("\n");
		//打分割线
		if (i < row - 1)
		{
			int j = 0;
			for (j = 0; j < col; j++)//有几列就有几组
			{
				printf("---");
				if (j < col - 1)
				{
					printf("|");
				}
			}
			printf("\n");
		}
	}
}

//下棋
//玩家先步
void PlayerMove(char board[ROW][COL], int row, int col)
{
	//给用户提供坐标
	int x = 0;
	int y = 0;
	printf("玩家下棋->");
	while (1)
	{
		printf("请输入要下的坐标,中间请用空格分隔->\n");
		scanf("%d %d", &x, &y);//用户输入之后,要判断用户输入的行数和列数是否合法
		if (x >= 1 && x <= row && y >= 1 && y <= col)//输入合法
		{
			//要注意从用户的角度去思考,用户只认为的第一行是从1开始的,而不是0
			if (board[x - 1][y - 1] == ' ')//分两种情况讨论
			{                              //1.位置没有被占用
				board[x - 1][y - 1] = '*';
				break;//输入正确就挑出玩家下棋的过程
			}
			else                           //2.位置已被占用
			{
				printf("该位置已被占用,请重新输入");
			}
		}
		else
		{
			printf("坐标非法,请重新输入:");
		}
	}
}

//电脑下棋
void ComMove(char board[ROW][COL], int row, int col)//可见,电脑和用户还是有很大区别的
{
	int x = 0;
	int y = 0;
	printf("电脑下棋->\n");
	//电脑下的位置是随机的  但是也要满足下棋的规则
	while (1)
	{
		x = rand() % row;//产生0-row-1的随机数
		y = rand() % col;
		if ( board[x][y] ==' ')
		{
			board[x][y] = '#';
			break;
		}
	}
	
}

int IsFull(char board[ROW][COL], int row, int col)
{
	int i = 0;
	int j = 0;
	for (i = 0; i < row; i++)
	{
		for (j = 0; j < col; j++)
		{
			if (board[i][j] == ' ')
				return 0;
		}
	}
	return 1;//找不到空格,证明满了,就是平局
}

int IsWin(char board[ROW][COL], int row, int col)
{
	//先判断赢
	//1.连成一行
	int i = 0;
	for (i = 0; i < row; i++)
	{
		if (board[i][0] == board[i][1] && board[i][1] == board[i][2] &&board[i][0]!=' ')
			return board[i][0];
	}
	//2.连成一列
	int j = 0;
	for (j = 0; j < col; j++)
	{
		if (board[0][j] == board[1][j] && board[1][j] == board[2][j] && board[0][j]!=' ')
			return board[0][j];
	}
	//3.对角线
	//主对角线
	if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[0][0]!=' ')
		return board[0][0];
	//次对角线
	if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[0][2]!=' ')
		return board[0][2];

	//平局
	if (IsFull(board,row,col) == 1)
		return 'Q';
	//继续
	return 'C';
}

test.c

#define _CRT_SECURE_NO_WARNINGS 1
//这个文件是游戏实现的文件
//三子棋游戏的实现
#include "game.h"
//菜单函数
void menu()
{
	printf("******************\n");
	printf("*****1 ->play*****\n");
	printf("*****0 ->exit*****\n");
}

//游戏函数
void game()
{
	char board[ROW][COL] = {0};
	
	//1.初始化棋盘  存放数据 ->二维数组      先用空格代替
	InitBoard(board, ROW, COL);
	
	//2.打印棋盘
	DisplayBoard(board, ROW, COL);

	//3.下棋并判断胜负
	char ret = ' ';
	while (1)//用循环模拟对战环节    下一步棋,打印一次
	{
		PlayerMove(board, ROW, COL);//玩家下棋
		DisplayBoard(board, ROW, COL);
		//判断输赢
		ret = IsWin(board, ROW, COL);
		if (ret != 'C')
			break;

		ComMove(board, ROW, COL);
		DisplayBoard(board, ROW, COL);
		//判断输赢
        ret = IsWin(board, ROW, COL);
		if (ret != 'C')
			break;
	}
	if (ret == '*')
		printf("玩家赢\n");
	else if (ret == '#')
		printf("电脑赢\n");
	else
		printf("平局\n");
	
}
int main()
{
	srand((unsigned int)time(NULL));
	int input = 0;
	do              
	{
		menu();//打印菜单
		scanf("%d",&input);
		//根据用户输入的内容来判断是否进行后续操作
		switch (input)
		{
			case 1:
				game();
				break;
			case 0:
				printf("退出游戏\n");
				break;
			default:
				printf("输入错误,请重新输入");
		}
	} while (input); //只有输入0的时候才会推出循环(0为假)
	return 0;
}

游戏截图(让电脑一盘!)

 

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

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

相关文章

二维数组---C语言(行列抽象思维)

目录 前言&#xff1a; 1.数组 1.1数组的初始化 1.2数组的访问方法 2.二维数组 2.1二维数组的创建和初始化 2.2二维数组的访问 2.3内存中的二维数组 ❤博主CSDN:啊苏要学习 ▶专栏分类&#xff1a;C语言◀ C语言的学习&#xff0c;是为我们今后学习其它语言打好基础&am…

探索 Elasticsearch 8.X Terms Set 检索的应用与原理

1、Terms Set 检索简介 Terms Set查询是Elasticsearch中一种强大的查询类型&#xff0c;主要用于处理多值字段中的文档匹配。 其核心功能在于&#xff0c;它可以检索至少匹配一定数量给定词项的文档&#xff0c;其中匹配的数量可以是固定值&#xff0c;也可以是基于另一个字段的…

快速排序、希尔排序、归并排序、堆排序、插入排序、冒泡排序、选择排序(递归、非递归)C语言详解

1.排序的概念及其运用 1.1排序的概念 排序&#xff1a;所谓排序&#xff0c;就是使一串记录&#xff0c;按照其中的某个或某些关键字的大小&#xff0c;递增或递减的排列起来的操作。 稳定性&#xff1a;假定在待排序的记录序列中&#xff0c;存在多个具有相同的关键字的记录&…

postman 的 console 窗口,助力 http 请求错误时的问题排查

postman 是个很不错的 http 请求测试工具&#xff0c;有时我们使用它发送 http 请求&#xff0c;但是因为各种原因&#xff0c;导致请求失败&#xff0c;没有 response 返回&#xff0c;可能只有一个状态码&#xff0c;这让我们排查起来非常困难&#xff0c;比如下图所示&#…

GitLab + Jenkins 实现持续集成CI

1 软件版本 2 基础环境安装 2.1 docker 安装 yum install -y docker-ce-20.10.16 systemctl start docker && systemctl enable docker docker version 2.2 docker-compose 安装 curl -L https://get.daocloud.io/docker/compose/releases/download/1.29.2/docker-c…

虚拟化无法开启

虚拟化无法开启 开启虚拟机&#xff0c;突然出现以下报错&#xff1a; 此主机支持 Intel VT-x&#xff0c;但 Intel VT-x 处于禁用状态。 如果已在 BIOS/固件设置中禁用 Intel VT-x&#xff0c;或主机自更改此设置后从未重新启动&#xff0c;则 Intel VT-x 可能被禁用。 (1…

modbus 协议地址

modbus 仿真软件 modbus slave: 用作 modbus 服务器(也叫做modbus从站), 通常用于仿真PLC设备.modbus poll: 用作 modbus 客户端(也叫做modbus主站), 用于仿真上位机程序, 通常使用它在现场验证PLC设备的modbus通讯是否OK 理解 modbus 寻址 modbus 分4个数据区, 实际因为第4区可…

【Redis】Redis 高性能IO模型原理

前言 在面试的时候遇到Redis肯定会问&#xff0c;Redis单线程为什么那么快呀&#xff1f;你可以说下你对IO多路复用的机制嘛。但是仔细一想Redis真的是单线程在运行处理嘛&#xff0c;其实这个单线程主要指的Redis的网络IO和键值对读写是由一个线程来完成的&#xff0c;Redis在…

深度学习—卷积神经网络简单理论及实践

卷积神经网络 传统意义上的多层神经网络只有输入层、隐藏层和输出层。其中隐藏层的层数根据需要而定&#xff0c;没有明确的理论推导来说明到底多少层合适。 卷积神经网络CNN&#xff0c;在原来多层神经网络的基础上&#xff0c;加入了更加有效的特征学习部分&#xff0c;具…

Docker 安装 elasticsearch、kibana、ik

一、安装elasticsearch 1. 拉取 elasticsearch 镜像 docker pull elasticsearch:7.6.2 2. 创建 elasticsearch 容器 docker run --name elasticsearch7.6.2 -d -e ES_JAVA_OPTS"-Xms512m -Xmx512m" --net host -e "discovery.typesingle-node" -p 92…

SpringCloud踩坑系列:Mybatis的Mapper报错

500错误&#xff0c; 报错信息如下&#xff1a; org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): org.cyf.serviceDriverUser.mapper.DriverUserMapper.select1 at org.apache.ibatis.binding.MapperMethod$SqlCommand.<init>(M…

判断两个时间段是否有交集

判断两个时间段是否有交集 前言&#xff1a;项目中遇到了类似会议室预约的时间段被占用&#xff0c;预约车辆时间段被占用等。 start&#xff1a;预约开始时间。 end&#xff1a;预约结束时间。 思考&#x1f914;&#xff1a; 那几种情况&#xff0c;可以正常预约&#x…

部署harbor私有镜像仓库

环境&#xff1a;所有机器都是centos7.4 一、部署harbor镜像仓库 机器IP&#xff1a;10.0.0.9 harbor服务器 1.下载harbor压缩包到服务器/root目录下[rootharbor~]#wget https://ghproxy.com/https://github.com/goharbor/harbor/releases/download/v2.5.3/harbor-offline-i…

【云计算•云原生】7.play with kubernetes在线实验环境

文章目录 1.play with kubernetes介绍2.搭建多节点nginx示例 1.play with kubernetes介绍 play with kubernetes网站链接 https://labs.play-with-k8s.com/每次登录提供4小时在线实验环境&#xff0c;最多可以开5个节点 2.搭建多节点nginx示例 点击左边的ADD NEW INSTANCE之…

网络路径下倾斜模型生产流程-倾斜生产

网络路径下倾斜模型生产流程-倾斜生产 全部控制点完成刺点后&#xff0c;检查无误后&#xff0c;点击Submit aerotriangulation。 选择使用控制点进行空三。 此时&#xff0c;将影像色彩平衡设置为Enabled&#xff0c;Position和Rotation设置为Compute。点击Submit开始空三。 …

知识管理工具,你选择语雀、Baklib、Notion还是FlowUs?

随着信息技术的不断发展&#xff0c;人们对于笔记软件的需求也越来越高。笔记软件可以帮助我们记录生活中的点滴&#xff0c;整理工作中的思路&#xff0c;提高工作效率和生活品质。然而&#xff0c;市面上的笔记软件种类繁多&#xff0c;选择一款适合自己使用的笔记软件也成为…

国产仪器 1763卫星帆板电源阵列模拟器

1763卫星帆板电源阵列模拟器用于解决卫星电源系统研制、航天器模拟供电系统测试等帆板电源阵列及二次供电设备的测量和分析&#xff0c;解决电源分系统功能验证、现场试验等无法使用真实的帆板电源等带来的难题&#xff0c;用于卫星或卫星测试系统以及太阳能逆变器中模拟太阳电…

【数据结构】Treap树堆

Treap树堆 Treap是一种平衡化二叉搜索树&#xff0c;在键值key满足二叉搜索树的前提下&#xff0c;增加了priority是满足堆序的条件。可以证明&#xff0c;如果priority的随机的&#xff0c;那么Treap的期望深度是 O ( l o g N ) O(logN) O(logN)&#xff0c;也就是说大部分操…

29从零开始学Java之如何正确创建Java里的类?

作者&#xff1a;孙玉昌&#xff0c;昵称【一一哥】&#xff0c;另外【壹壹哥】也是我哦 千锋教育高级教研员、CSDN博客专家、万粉博主、阿里云专家博主、掘金优质作者 前言 在上一篇文章中&#xff0c;壹哥给大家介绍了面向对象和面向过程的概念&#xff0c;并介绍了两者的区…

【MySQL】数据库的基本操作三:增删改查进阶

目录 &#x1f31f;一、数据库约束 &#x1f308;1、Null约束&#xff1a;创建表时&#xff0c;可以指定某列不能为空。 &#x1f308;2、Unique约束&#xff1a;唯一约束 &#x1f308;3、Default约束&#xff1a;默认值约束 &#x1f308;4、Primary Key&#xff1a;主键…