C语言小项目之三子棋

news2024/11/28 14:37:34

💓博主CSDN主页:杭电码农-NEO💓

⏩专栏分类:C语言学习分享⏪

🚚代码仓库:NEO的学习日记🚚

🌹关注我🫵带你学习更多C语言知识
  🔝🔝


在这里插入图片描述


三子棋

  • 1. 前言📕
  • 2. 思路分析📕
    • 2.1 创建文件📗
    • 2.2 实现功能需要的函数📗
    • 2.3 main函数代码思考📗
  • 3. 代码实现📕
    • 3.1 main函数📗
    • 3.2 game.h源文件📗
    • 3.3 初始化函数📗
    • 3.4 打印棋盘📗
    • 3.5 玩家下棋📗
    • 3.6 电脑下棋📗
    • 3.7 game函数的设计📗
    • 3.8 判断棋盘是否满格📗
    • 3.9 判断输赢📗
  • 4. 所有代码📕

1. 前言📕

我们学习完数组之后,可以自己做一些小游戏来巩固我们的知识,
这里的三子棋就是其中一个偏简单的小游戏.详细的实现请看下面的分析

在这里插入图片描述


2. 思路分析📕

2.1 创建文件📗

  • 我们之前写代码的时候实现的功能很单一,就直接创建一个test.c文件,所有代码都在这个文件里面实现就可以了.

  • 但是当我们真正要做一个项目的时候,不管项目大或小,我们都要让我们的这个项目看起来更加规范,并且我们在实现完功能后我们希望自己能运行一下代码看看我们写的对不对.

  • 所以这里就引出了一个写项目常见的手段:创建多个文件夹分别实现不同的功能

在这里插入图片描述
这里在源文件中,我们需要自己定义三个文件,分别是:

  • game.c,用来实现游戏功能的文件📖
  • game.h,用来声明函数和包含头文件的文件📖
  • test.c,用来测试我们写的代码正确与否的文件📖

在本次游戏设计中,使用到了3个文件,为什么不能放在一个文件中?三子棋的实现需要多个模块的功能相互串联,多个文件可以分别处理各自模块的功能,能更好处理各个模块之间的逻辑并且便于后期调试,也使得代码的可读性提高。

我们可以将test.c文件与其他两个源文件区别开来,方便观察:

如何将不同源文件分开


2.2 实现功能需要的函数📗

众所周知啊,玩三子棋的时候是在九宫格中玩的,所以这里我们需要定义一个3×3的数组来充当我们的九宫格,这里数组中可能会存放我们下的棋子,所以我们在每次开始游戏之前都应该初始化一下数组内容

我们下棋当然要能看见棋盘了,并且要看见我们下的棋和电脑下的棋,所以这里我们需要一个打印功能

下棋分玩家下棋和电脑下棋,并且有先后顺序,所以这里我们需要单独完成两个功能:电脑随机下一个位置,玩家从键盘输入想要下的位置

根据上面的一些写法,我们现在可以暂时总结出我们需要的函数有:

  • InitBoard,初始化棋盘
  • DisplayBoard,打印棋盘
  • PlayerMove,玩家下棋
  • ComputerMove,电脑下棋

这名字你可以自己修改,但是应该要包含上面这些功能


2.3 main函数代码思考📗

  • 我们希望玩家自行选择想不想要玩游戏,假如有些人玩了一把不过瘾还想玩一把,亦或者是有人玩了一把腻了不想玩了,都是玩家自己决定的.

  • 所以我们可以在main函数中设计一个switch语句,用于判断玩家的输入,继续玩下去可以输入1,不想玩了可以输入0退出.

  • 并且main函数中应该创建3×3的数组来代表九宫格,以便被各个函数所调用并且我们下棋想要用*和#的话,应该创建一个二维的字符型数组

有了大致的思路后,接下来我们就一边写代码一边解释和思考


3. 代码实现📕

3.1 main函数📗

void menu()//菜单,选择1或0.
{
	printf("*****************************\n");
	printf("********  1. play   *********\n");
	printf("********  0. exit   *********\n");
	printf("*****************************\n");
}

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

	return 0;
}

在main函数中,我们想要实现刚刚想到的功能,所以这里我们使用do…while语句,保证语句至少执行一次,当我们输入1时,才会进入到我们的游戏中,这里我暂且把游戏的实现代码放在void game(void)中.


3.2 game.h源文件📗

我们在test.c和game.c文件中都使用了printf和scanf等库函数,所以我们将常见的头文件包含在game.h中,再在game.c和test.c中包含game.h的文件即可

#include<stdio.h>
#include<stdlib.h>//电脑下棋生成随机数需要引用的头文件
#include<time.h>
#define row 3//将数组的行和列用define宏定义
#define col 3

//初始化棋盘
void InitBoard(char board[row][col], int r, int c);
//打印棋盘
void DisplayBoard(char board[row][col], int r, int c);
//玩家下棋
void PlayerMove(char board[row][col], int r, int c);
//电脑下棋
void ComputerMove(char board[row][col], int r, int c);

引用了常见的头文件后,我们还需要在game.h文件中声明我们之前提到过的函数,这里的r和c代表二维数组的行数也列数


3.3 初始化函数📗

我们想要在每次开始游戏之前将棋盘上所有数据清除,就是将棋盘初始化,将数组所有元素初始化为空格:

void InitBoard(char board[row][col], int r, int c)
{
	for (int i = 0; i < r; i++)
	{
		for (int j = 0; j < c; j++)
		{
			board[i][j] = ' ';
		}
	}
}

3.4 打印棋盘📗

如果我们直接将二维数组中所有元素都打印出来,它看起来并不是很美观,所以这里我们加上一些分割线和换行,使我们的九宫格更加立体.如下

在这里插入图片描述

void DisplayBoard(char board[row][col], int r, int c)
{
	int i = 0;
	for (i = 0; i < row; i++)
	{
		//1. 打印数据
		int j = 0;
		for (j = 0; j < col; j++)
		{
			printf(" %c ", board[i][j]);
			if (j < col - 1)
				printf("|");
		}
		printf("\n");
		//2. 打印分割线
		if (i < row - 1)
		{
			int j = 0;
			for (j = 0; j < col; j++)
			{
				printf("---");
				if (j < col - 1)
					printf("|");
			}
			printf("\n");
		}
	}
}

当然 ! 如果你是自己玩,并且不是颜控,直接把数组打印出来也是欸有任何问题的


3.5 玩家下棋📗

玩家下棋时需要注意,玩家有可能输入的坐标位置已经有棋子了,或者输入的坐标位置在九宫格之外,所以这里当玩家键盘输入后,我们应该判断下棋的位置是否正确,如果输入的位置不正确,我们将一直重复这个过程直到输入正确的位置,所以这里我们给一个while(1)语句,恒为真,当输入坐标合法时才跳出while语句

void PlayerMove(char board[row][col], int r, int c)
{
	while (1)
	{
		printf("请选择下棋的坐标:");
		int x, y;
		scanf("%d %d", &x, &y);
		if (x > row || y > col)
		{
			printf("坐标选择越界\n");
		}
		else if (board[x - 1][y - 1] == ' ')
		{
			board[x - 1][y - 1] = '*';//将玩家输入的正确坐标赋值'*'后,break跳出while循环
			break;//如果这里不跳出循环,玩家会一直下棋
		}
		else
		{
			printf("此位置已有棋子\n");
		}
	}
}

并且我们知道,数组的下标是从0开始的,但是不是每一个玩三子棋的人都是程序员,所以我们应该将玩家输入的横纵坐标减一得到它在数组中的位置,比如:玩家输入 2 3,就是下在第二行第三列,但是数组的第二行第三列是board [ 1 ] [ 2 ];


3.6 电脑下棋📗

这里的电脑下棋是生成随机位置下棋,是不具有智能化手段的,所以这里我们首先要生成两个随机数来作为下子的横纵坐标,这里我们用到库函数rand(),rand是生成随机数的函数,它生成的数可大可小,所以这里生成的随机数有可能超出我们棋盘的范围,这里我们的棋盘是九宫格,3×3的棋盘,所以我们希望它生成的坐标在0~2之间来满足要求所以我们这样写:

int x=rand()%3;//横坐标
int y=rand()%3;//纵坐标

因为一个数对三取余一定比三要小,它只能为0 1 2,这正和我意.所以我们常常在rand()函数后面加一个取余操作来确定我们生成的随机数在一个范围内

void ComputerMove(char board[row][col], int r, int c)
{
	
	while (1)
	{
		int x, y;
	    printf("电脑下棋:\n");
		x = rand() % row;
		y = rand() % col;
		if (board[x - 1][y - 1] == ' ')//判断生成的随机位置是是不是没有下过数据
		{
			board[x - 1][y - 1] = '#';
			break;
		}
	}
}

这里和玩家下棋一样,生成了3以内的两个数字后,要判断这个位置是否已经下过棋子了,只有生成了正确的位置,才会跳出while循环


3.7 game函数的设计📗

我们的思路是.先初始化棋盘,然后再将棋盘打印出来后,让玩家开始下棋,玩家下了一个子后立马又打印棋盘,并且判断输赢,如果没赢,那么电脑再继续下棋,下子后马上又打印棋盘,并且判断电脑是否赢了,.所以这个地方我们还需要设计一个判断输赢的函数,并且还有一个问题就是当棋盘下满棋子了还没有人赢,那么这就是平局,所以我们还需要写一个函数来判断棋盘是否已满

但是不管怎么样我们先把游戏的大致过程给写出来:

void game()
{
	char board[row][col] = { 0 };//定义一个二维数组
	//初始化棋盘
	InitBoard(board, row, col);
	//打印棋盘
	DisplayBoard(board, row, col);
	//下棋
	char ret = 0;//ret用来判断对局是否结束
	while (1)
	{
		//玩家下棋
		PlayerMove(board, row, col);
		DisplayBoard(board, row, col);//下子后立马打印棋盘
		//判断输赢
		ret = IsWin(board, row, col);//判断输赢函数返回的是C,证明没有人赢,游戏继续
		if (ret != 'C')
			break;
		//电脑下棋
		ComputerMove(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");
}

3.8 判断棋盘是否满格📗

int IsFull(char board[row][col], int r, int c)
{
	int i = 0;
	for (i = 0; i < row; i++)
	{
		int j = 0;
		for (j = 0; j < col; j++)
		{
			if (board[i][j] == ' ')
			{
				return 0;//棋盘没有满
			}
		}
	}
	return 1;//棋盘满了
}

只有棋盘中有空格就证明棋盘没有被下满,如果九宫格遍历完都没有空格,证明棋盘满了.这里的返回值你可以自行设定,你甚至可以写成布尔值true或false.🎉🎉🎉


3.9 判断输赢📗

我们首先要知道什么情况下算赢了:

在这里插入图片描述
一共有八种情况,一个正方形的四条边加中间一个"米"字,都是赢.所以我们这样来设计代码:

char IsWin(char board[row][col], int r, int c)
{
	//赢
	//行
	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];//我们返回这三个元素中任意一个元素,如果玩家赢那么game函数就接受到'*',如果电脑赢就接受到'#'
		}
	}
	//列
	for (i = 0; i < col; i++)
	{
		if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[0][i] != ' ')//列的判断和行一样
		{
			return board[0][i];
		}
	}
	//对角线
	if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[1][1] != ' ')
		return board[1][1];
	if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[1][1] != ' ')
		return board[1][1];

	//平局
	if (IsFull(board, row, col) == 1)//如果IsFull返回1,证明棋盘满了,平局
	{
		return 'Q';
	}
	//继续
	return 'C';//返回C代表没有人赢并且棋盘没有满,就继续下子
}

这里我们将判断输赢函数的返回值设计为 ’ * ’ ,‘#’ ,‘Q’ ,和’C’,其实还是有目的的,game函数的ret如果接受到判断输赢函数的返回值如果不是’C’了,证明有输赢产生,但是我并不知道是玩家赢还是电脑赢,这里玩家下子是’ * ‘,电脑下子是’ # ',所以最后我们只需要判断返回值是什么就可以判断谁赢了.


接下来我们运行看看:

三子棋下棋

4. 所有代码📕

  • test.c
#define _CRT_SECURE_NO_WARNINGS
#pragma warning(disable:6031)
#include"game.h"

void menu()
{
	printf("*****************************\n");
	printf("********  1. play   *********\n");
	printf("********  0. exit   *********\n");
	printf("*****************************\n");
}

void game()
{
	char board[row][col] = { 0 };
	InitBoard(board, row, col);
	//打印棋盘
	DisplayBoard(board, row, col);
	//下棋
	char ret = 0;
	while (1)
	{
		//玩家下棋
		PlayerMove(board, row, col);
		DisplayBoard(board, row, col);
		//判断输赢
		ret = IsWin(board, row, col);
		if (ret != 'C')
			break;
		//电脑下棋
		ComputerMove(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()
{
	int input = 0;
	srand((unsigned int)time(NULL));
	do
	{
		menu();
		printf("请选择:>");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			game();
			break;
		case 0:
			printf("退出游戏\n");
			break;
		default:
			printf("选择错误,重新选择!\n");
			break;
		}
	} while (input);

	return 0;
}

  • game.c
#define _CRT_SECURE_NO_WARNINGS
#pragma warning(disable:6031)
#include"game.h"

void InitBoard(char board[row][col], int r, int c)
{
	for (int i = 0; i < r; i++)
	{
		for (int j = 0; j < c; j++)
		{
			board[i][j] = ' ';
		}
	}
}

void DisplayBoard(char board[row][col], int r, int c)
{
	int i = 0;
	for (i = 0; i < row; i++)
	{
		//1. 打印数据
		int j = 0;
		for (j = 0; j < col; j++)
		{
			printf(" %c ", board[i][j]);
			if (j < col - 1)
				printf("|");
		}
		printf("\n");
		//2. 打印分割线
		if (i < row - 1)
		{
			//printf("---|---|---\n");
			int j = 0;
			for (j = 0; j < col; j++)
			{
				printf("---");
				if (j < col - 1)
					printf("|");
			}
			printf("\n");
		}
	}
}


void PlayerMove(char board[row][col], int r, int c)
{
	
	while (1)
	{
		printf("请选择下棋的坐标:");
		int x, y;
		scanf("%d %d", &x, &y);
		if (x > row || y > col)
		{
			printf("坐标选择越界\n");
		}
		else if (board[x - 1][y - 1] == ' ')
		{
			board[x - 1][y - 1] = '*';
			break;
		}
		else
		{
			printf("此位置已有棋子\n");
		}
	}
}

void ComputerMove(char board[row][col], int r, int c)
{
	
	while (1)
	{
		int x, y;
	    printf("电脑下棋:\n");
		x = rand() % row;
		y = rand() % col;
		if (board[x][y] == ' ')
		{
			board[x][y] = '#';
			break;
		}
	}
}

int IsFull(char board[row][col], int r, int c)
{
	int i = 0;
	for (i = 0; i < row; i++)
	{
		int j = 0;
		for (j = 0; j < col; j++)
		{
			if (board[i][j] == ' ')
			{
				return 0;
			}
		}
	}
	return 1;
}

char IsWin(char board[row][col], int r, int c)
{
	//赢
	//行
	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];
		}
	}
	//列
	for (i = 0; i < col; i++)
	{
		if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[0][i] != ' ')
		{
			return board[0][i];
		}
	}
	//对角线
	if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[1][1] != ' ')
		return board[1][1];
	if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[1][1] != ' ')
		return board[1][1];

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



  • game.h
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define row 3
#define col 3

//初始化棋盘
void InitBoard(char board[row][col], int r, int c);
//打印棋盘
void DisplayBoard(char board[row][col], int r, int c);
//玩家下棋
void PlayerMove(char board[row][col], int r, int c);
//电脑下棋
void ComputerMove(char board[row][col], int r, int c);

char IsWin(char board[row][col], int r, int c);

int IsFull(char board[row][col], int r, int c);



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

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

相关文章

【英】考虑多能负荷不确定性的区域综合能源系统鲁棒规划(MatlabPython代码)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

寅家科技完成近亿元B1轮融资,加速高阶智能驾驶布局

近日&#xff0c;寅家科技宣布完成近亿元人民币B1轮融资&#xff0c;本轮融资由东方富海、深创投、深圳高新投联合投资&#xff0c;所募资金主要用于公司高阶智能驾驶技术产品的研发迭代&#xff0c;以及智能驾驶产品量产、海外市场开拓&#xff0c;从而进一步提升核心产品的市…

Solow模型推导模拟

Solow模型推导模拟 文章目录 Solow模型推导模拟[toc]1 Solow模型推导2 Solow模型模拟 1 Solow模型推导 在存在资本折旧、技术进步和人口增长条件下&#xff0c;有效劳动人均资本为 k ˙ ( t ) K ˙ ( t ) A ( t ) L ( t ) − K ( t ) [ A ( t ) L ( t ) ] 2 [ A ( t ) L ˙ …

腾讯云网站备案流程步骤、备案审核通过时间详细说明

腾讯云网站备案流程先填写基础信息、主体信息和网站信息&#xff0c;然后提交备案后等待腾讯云初审&#xff0c;初审通过后进行短信核验&#xff0c;最后等待各省管局审核&#xff0c;前面腾讯云初审时间1到2天左右&#xff0c;最长时间是等待管局审核时间&#xff0c;网站备案…

css新手引导实现方式总结

新手引导功能一般都是用一个半透明的黑色进行遮罩&#xff0c;蒙层上方对界面进行高亮&#xff0c;旁边配以弹窗进行讲解&#xff0c;样式如下 但是由于交互不同&#xff0c;实现方案也不一样&#xff0c;下面就针对不用的交互&#xff0c;总结了不同的实现方法&#xff08;下文…

路由和寻址的区别

如果说传输层协议&#xff0c;除了 TCP/UDP&#xff0c;我们还可以有其他选择&#xff0c;比如 Google 开发的 QUIC 协议&#xff0c;帮助在传输层支持 HTTP 3.0 传输。但是在网络层&#xff0c;IP 协议几乎一统天下。IP 协议目前主要有两个版本 IPv4 和 IPv6。 根据 Google 统…

开发者一定要知道的 API 管理五大趋势

API First 大势所趋&#xff0c;APIaaS&#xff08;API 作为服务&#xff09;也将受到越来越多企业和组织的选择&#xff0c;研发团队对 API 研发管理工具的要求也水涨船高。 API 在今天的数字化世界中扮演着至关重要的角色&#xff0c;随着云计算、物联网、微服务尤其是 AI 等…

Uniapp 引入uView-ui 插件

前言 最近在写uniapp&#xff0c;用了一下原生的ui框架感觉不是很好看&#xff0c;打算去插件市场上面找一下好看的UI插件。学习不是闭门造车&#xff0c;自己重复造轮子。能自己解决和会不会用别人的方法是两回事。我自己也能写UI界面逻辑&#xff0c;但是这样太费时间了。最…

线宽变大,损耗变小;线宽无限大,损耗无限小?

一博高速先生成员&#xff1a;黄刚 作为高速信号传输的重要的指标之一&#xff0c;损耗&#xff0c;无论是对硬件工程师&#xff0c;设计工程师还是我们SI工程师来说&#xff0c;都会是非常的关注。而对于像背板传输这种长距离的走线系统或是像芯片测试板要求损耗极小的情况&a…

港联证券|港交所内地路演人气爆棚 新一轮上市改革加速推进

5月10日&#xff0c;香港交易所在深圳举行未来科技峰会&#xff0c;拉开了港股特专科技上市新规内地路演推广的序幕。 今年3月底&#xff0c;港交所正式推出特专科技公司上市新规&#xff0c;《主板上市规则》新增18C章&#xff0c;并于3月31日起接收特专科技公司上市申请&…

JavaWeb《后端内容:2. MVC-ServletContext-IOC-事务管理-过滤器Filter》

目录 1. 准备和回顾 2. MVC-reflect 3. MVC-dispatcherServlet 3.1 思路部分 3.2 Debug部分 3.3 基于controller进行优化 4. Servlet-api 4.1 回顾 4.2 Init方法 1. 获取ServletConfig config getServletConfig(); 2. 获取初始化参数值&#xff1a;config.getInitP…

静态库(lib),动态库(dll)

我之前有一篇文章讲过静态链接库和动态链接库&#xff0c;大家可以点击链接去看一下&#xff1a;静态链接库&#xff0c;动态链接库【滴水逆向三期48笔记】&#xff0c;由于不是系统学习Windows编程&#xff0c;感觉那时候就是囫囵吞枣&#xff0c;今天又学习了一遍&#xff0c…

基于Keil生成外部Nor Flash下载算法,并使用J-Flash直接烧录(以W25Q64为例)

需要的软件&#xff1a; Keil STM32CubeMX J-Flash 参考文档&#xff1a; 方法1&#xff1a;在Keil中点击Help→uVision Help&#xff0c;然后再搜索框中输入FLM&#xff0c;点击列出主题&#xff0c;可以看到生成下载算法的大致步骤&#xff1a; 方法2&#xff1a;在ARM Ke…

带你玩转三子棋—【C语言】

目录 前言&#xff1a; 1. 菜单的打印 2. game函数的实现 2.1 初始化棋盘 2.2 显示棋盘 2.3 玩家下棋 2.4 电脑下棋 2.5 判断输赢 2.6 判断棋盘是否满了 3. 全部代码 3.1 game.h 3.2 game.c 3.3 test.c 前言&#xff1a; 为了实现三子棋&#xff0c;首先我们应该…

frp将配置写在代码中重新打包

frp 是一个专注于内网穿透的高性能的反向代理应用&#xff0c;支持 TCP、UDP、HTTP、HTTPS 等多种协议。可以将内网服务以安全、便捷的方式通过具有公网 IP 节点的中转暴露到公网。在有些情况下我们需要隐藏配置信息&#xff0c;尤其是客户端&#xff08;比如我们要在第三方电脑…

第五章 总结及作业(123)【编译原理】

第五章 作业【编译原理】 前言推荐第五章 总结5.1自下而上分析基本问题 5.1.1归约5.1.2规范归约简述5.1.3 符号栈的使用与语法树的表示 5.2 算符优先分析5.2.1算符优先文法及优先表构造算法&#xff1a;构造FIRSTVT集算法&#xff1a;构造LASTVT集算法&#xff1a;构造优先表5.…

Google I/O 2023 - 一文快速总结 Flutter Dart 的现状和未来

随着 Google I/O 2023 的发布&#xff0c; Flutter 3.10 和 Dart 3.0 也都正式发&#xff0c;不得不说如今 Dart 的版本号终于快追上 Flutter 得版本号了&#xff0c;特别随着 Dart 3 的发布&#xff0c; Flutter 在 records 和 patterns 的加持下&#xff0c;开发体验终于开始…

LlamaIndex :面向QA 系统的全新文档摘要索引

在这篇博文中&#xff0c;我们介绍了一种全新的 LlamaIndex 数据结构&#xff1a;文档摘要索引。我们描述了与传统语义搜索相比&#xff0c;它如何帮助提供更好的检索性能&#xff0c;并通过一个示例进行了介绍。 背景 大型语言模型 (LLM) 的核心场景之一是对用户自己的数据进…

MapReduce框架

TextInputFormat 1&#xff09;FileInputFormat实现类 思考&#xff1a;在运行MapReduce程序时&#xff0c;输入的文件格式包括&#xff1a;基于行的日志文件、二进制格式文件、数据库表等。那么&#xff0c;针对不同的数据类型&#xff0c;MapReduce是如何读取这些数据的呢&…

Postman 如何关联接口测试并设置全局变量(带有token鉴权)

一、登陆接口 创建一个request请求 在Tests中添加JavaScript代码&#xff0c;用来获取鉴权&#xff1a; var jsonData JSON.parse(responseBody); var Authorization jsonData.data.access_token; console.log(Authorization) pm.globals.set(‘Authorization’,Authorizatio…