java 马踏棋盘优化_我所知道的十大常用算法之马踏棋盘算法(深度搜索、贪心思想优化 )...

前言需求

今天我们学习的是马踏棋盘算法,我们还是从一个场景里引入看看

64ae664777dbca2596265acde681595c.png

马踏棋盘算法也被称为骑士周游问题

将马随机放在国际象棋的6×6棋盘Board0~5的某个方格中

提示:马按走棋规则(马走日字)进行移动

要求:每个方格只进入一次,走遍棋盘上全部64个方格

一、马踏棋盘问题

马踏棋盘问题(骑士周游问题)实际上是:图的深度优先搜索(DFS)的应用

还记得图的深度优先搜索(DFS)吗?

有些模糊或者不记得小伙伴可以看往期文章:图(广度优先与深度优先)

44f62560a31e20d11d27c0bbf5f60839.png

那么按照我们的简单思路,是不是要一个位置一个位置去踩坑看看?

78d9f2c2e6c36d17d0d0bc933245fca0.png

f4918f6685262ff554b9a34d29baf217.png

那么按照我们的深度优先搜索,就要一步步走下去,直至达成任务

4517db3b7db280cdd94535f283b5c6ad.png

当我们的所选第三步的位置,无法达成完成任务

那么我们需要回溯,将原第三步更换到下一个位置里去

cf4c33e323f1637ae1e09c49c44c12ce.png

在以新第三步开始,进行搜索,也要一步步走下去,直至达成任务

ad610b1e3007639c4ee17890b5769cdf.png

二、通过示例来认识算法

根据我们之前简单的思路,首先我们需要创建一个棋盘的数组

当我们做出选择下一步的时候,我们需要将当前的位置标记为已访问,并根据当前位置计算出马儿能走那些位置,并放入到一个集合中里去

0bfa96a2df835e8c7b420d4c2679ed73.png

当然我们可以根据棋盘的情况来判断是否可以进行计算

afb72b16aa501a25bbcdfd91df661a2e.png

注意::马儿不同的走法、会得到不同的结果,效率也会有影响(需优化)

规则判断是否可走

那么我怎么知道这些位置是否可走呢?我是怎么计算出来的呢?

3eb2ea5facbdc0c71d87291e830ccc5a.png

首先我们先分析当前位置的x、y坐标,按照规则进行计算:(马走日字)

fe9c2e068ff523ff785a5e1e33d7fa3c.png

我们先分析一下象棋里的马走日是怎么样的吧

4bad631ccbf9992680f9dfa13ee2f898.png

马走日所说的是马从提棋位置到落棋位置是一个“日”子的对角线,在没有棋子踩住马脚时,马是可以随意走哪个方向的日字都是可以的

5559ada7359accafe530a9527de2b69c.png

572d89e691ddd657e9fd228b2625294f.png

在有其他棋子在马的如图相关位置时,马就不能走该方向的日字了,我们也熟称“踩马脚了”。注意无论踩马脚的棋子是己方的棋子还是敌方的棋子,被踩方向的日字都不能走了

e4e6785cf0edfc73d03bda243e8d12fe.png

如果四只马脚都被踩了,那么这只马哪里都走不了了(如图)

6bc680da15b64d756c28e287e08cf669.png

在我们这个问题中,还请你看图关联看懂马儿怎么走的,即称马走日

2c801dc037f56aede7ad8b217a4171b0.png

当我们知道规则怎么玩了,就可以从图上看出来,每个点与当前点的关系

0a24615bea069a4299665a430136e1f7.png

那么我们的马儿剩下的点与当前是什么关系呢?怎么走呢?

c9ac43170670910bc7631388b7b1ca19.png

骑士周游算法思路

我们创建一个类存放棋盘行、列,并记录棋盘上的是否被访问过public class HorseChessboard {

private static int x;//棋盘的列数

private static int y;//棋盘的行数

//创建一个数组,标记棋盘的各个位置是否被访问过

private static boolean visited[];

//使用一个属性,标记是否棋盘的所有位置都被访问

private static boolean finished; // 如果为true,表示成功

}

我们使用Point 类来表示 (x, y) 坐标空间中的位置的点public class Point extends Point2D implements java.io.Serializable {

public int x;

public int y;

private static final long serialVersionUID = -5276940640259749850L;

public Point() {

this(0, 0);

}

public Point(Point p) {

this(p.x, p.y);

}

public Point(int x, int y) {

this.x = x;

this.y = y;

}

//以双精度型返回点的 X 坐标。

public double getX() {

return x;

}

//以双精度型返回点的 Y 坐标。

public double getY() {

return y;

}

//返回此点的位置。

@Transient

public Point getLocation() {

return new Point(x, y);

}

//将点的位置设为指定位置

public void setLocation(Point p) {

setLocation(p.x, p.y);

}

//将此点更改为具有指定位置

public void setLocation(int x, int y) {

move(x, y);

}

//将此点的位置设为指定的双精度坐标

public void setLocation(double x, double y) {

this.x = (int) Math.floor(x+0.5);

this.y = (int) Math.floor(y+0.5);

}

//将此点移动到 (x,y) 坐标平面中的指定位置。

public void move(int x, int y) {

this.x = x;

this.y = y;

}

//平移 (x,y) 位置的点,沿 x 轴平移 dx,沿 y 轴平移 dy,移动后得到点 (x+dx, y+dy)

public void translate(int dx, int dy) {

this.x += dx;

this.y += dy;

}

//确定两个点是否相等。

public boolean equals(Object obj) {

if (obj instanceof Point) {

Point pt = (Point)obj;

return (x == pt.x) && (y == pt.y);

}

return super.equals(obj);

}

// 返回此点的字符串表示形式及其在 (x,y) 坐标空间中的位置

public String toString() {

return getClass().getName() + "[x=" + x + ",y=" + y + "]";

}

}

2af7fbe742170faa3cde0fb3d6b8cc6b.png

根据思路,需要根据当前位置判断马儿能走那些位置,并将结果放入ArrayList集合中

e426d11ddb5f51ff7babb7849b0b1668.pngpublic class HorseChessboard {

//省略其他关键性代码....

/**

* 功能:根据当前位置(Point对象),计算马儿还能走哪些位置(Point),并放入到一个集合中(ArrayList),最多有8个位置

* @param curPoint

* @return

*/

public static ArrayList next(Point curPoint){

ArrayList ps = new ArrayList<>();

//创建一个点

Point p1 = new Point();

//判断马儿是否能走5的位置

if((p1.x = curPoint.x - 2) >=0 && (p1.y = curPoint.y+1) >=0 ){

ps.add(new Point(p1));

}

return ps;

}

}

而其他点的位置与当前位置关系,我们之前也使用图解的方式分析,现在代码实现

f45b2e50b8c502d7da8b33bce6c2c922.pngpublic class HorseChessboard {

//省略其他关键性代码....

/**

* 功能:根据当前位置(Point对象),计算马儿还能走哪些位置(Point),并放入到一个集合中(ArrayList),最多有8个位置

* @param curPoint

* @return

*/

public static ArrayList next(Point curPoint){

ArrayList ps = new ArrayList<>();

//创建一个点

Point p1 = new Point();

//表示马儿可以走5这个位置

if((p1.x = curPoint.x - 2) >= 0 && (p1.y = curPoint.y -1) >= 0) {

ps.add(new Point(p1));

}

//判断马儿可以走6这个位置

if((p1.x = curPoint.x - 1) >=0 && (p1.y=curPoint.y-2)>=0) {

ps.add(new Point(p1));

}

//判断马儿可以走7这个位置

if ((p1.x = curPoint.x + 1) < x && (p1.y = curPoint.y - 2) >= 0) {

ps.add(new Point(p1));

}

//判断马儿可以走0这个位置

if ((p1.x = curPoint.x + 2) < x && (p1.y = curPoint.y - 1) >= 0) {

ps.add(new Point(p1));

}

//判断马儿可以走1这个位置

if ((p1.x = curPoint.x + 2) < x && (p1.y = curPoint.y + 1) < y) {

ps.add(new Point(p1));

}

//判断马儿可以走2这个位置

if ((p1.x = curPoint.x + 1) < x && (p1.y = curPoint.y + 2) < y) {

ps.add(new Point(p1));

}

//判断马儿可以走3这个位置

if ((p1.x = curPoint.x - 1) >= 0 && (p1.y = curPoint.y + 2) < y) {

ps.add(new Point(p1));

}

//判断马儿可以走4这个位置

if ((p1.x = curPoint.x - 2) >= 0 && (p1.y = curPoint.y + 1) < y) {

ps.add(new Point(p1));

}

return ps;

}

}

那么会不会有小伙伴有疑惑??

为什么走五那个位置就要>=0呢,走七的位置就要

我们先分析走五的位置的时候,为什么要>=0

3c9a6728ce603ef5fbb36746c97cf12b.png

同理,小于x,小于y代表我们只选择在棋盘内的点,超出的则不能走

骑士周游算法实践

往期我们使用的是二维数组代表这个点是否被访问过

但这里是36步都需要走一遍,那么我们其实可以使用一维数组进行表示

c64a2ef27a0a594cff4861eda2074038.png

这样我们可以是用公式:马儿所在行 * 棋盘行 +马儿所在列 = 马儿下标 + 1public class HorseChessboard {

//省略其他关键性代码....

/**

* 完成骑士周游问题的算法

* @param chessboard 棋盘

* @param row 马儿当前的位置的行 从0开始

* @param column 马儿当前的位置的列 从0开始

* @param step 是第几步 ,初始位置就是第1步

*/

public static void traversalChessboard(int[][] chessboard, int row, int column, int step) {

//标记当前棋盘执行的是第几步

chessboard[row][column] = step;

//row = 3 X = 6 column = 3 = 3 * 6 + 3 = 21 -1 = 20

visited[row * x + column] = true; //标记该位置已经访问

//获取当前位置可以走的下一个位置的集合

ArrayList ps = next(new Point(column, row));

}

}

当我们获取到当前位置可以走的下一个位置的集合,就进行遍历递归public class HorseChessboard {

//省略其他关键性代码....

/**

* 完成骑士周游问题的算法

* @param chessboard 棋盘

* @param row 马儿当前的位置的行 从0开始

* @param column 马儿当前的位置的列 从0开始

* @param step 是第几步 ,初始位置就是第1步

*/

public static void traversalChessboard(int[][] chessboard, int row, int column, int step) {

//标记当前棋盘执行的是第几步

chessboard[row][column] = step;

//row = 3 X = 6 column = 3 = 3 * 6 + 3 = 21 -1 = 20

visited[row * x + column] = true; //标记该位置已经访问

//获取当前位置可以走的下一个位置的集合

ArrayList ps = next(new Point(column, row));

//遍历 ps

while(!ps.isEmpty()) {

Point p = ps.remove(0);//取出下一个可以走的位置

//判断该点是否已经访问过

if(!visited[p.y * X + p.x]) {//说明还没有访问过

traversalChessboard(chessboard, p.y, p.x, step + 1);

}

}

}

}

我们怎么区分当前节点的可以走的下一个位置的集合,是否一路就成功了呢?

使用step 和 应该走的步数比较:step = X * Y

假如当前节点的可以走的下一个位置的集合,没有一路就成功,怎么办?

取消该位置已访问,并将棋盘置为0,说明该节点处于回溯状态public class HorseChessboard {

//省略其他关键性代码....

/**

* 完成骑士周游问题的算法

* @param chessboard 棋盘

* @param row 马儿当前的位置的行 从0开始

* @param column 马儿当前的位置的列 从0开始

* @param step 是第几步 ,初始位置就是第1步

*/

public static void traversalChessboard(int[][] chessboard, int row, int column, int step) {

chessboard[row][column] = step;

//row = 4 X = 8 column = 4 = 4 * 8 + 4 = 36

visited[row * x + column] = true; //标记该位置已经访问

//获取当前位置可以走的下一个位置的集合

ArrayList ps = next(new Point(column, row));

//遍历 ps

while(!ps.isEmpty()) {

Point p = ps.remove(0);//取出下一个可以走的位置

//判断该点是否已经访问过

if(!visited[p.y * x + p.x]) {//说明还没有访问过

traversalChessboard(chessboard, p.y, p.x, step + 1);

}

}

//判断马儿是否完成了任务,使用 step 和应该走的步数比较 ,

//如果没有达到数量,则表示没有完成任务,将整个棋盘置0

//说明: step < X * Y 成立的情况有两种

//1. 棋盘到目前位置,仍然没有走完

//2. 棋盘处于一个回溯过程

if(step < x * y && !finished ) {

chessboard[row][column] = 0;

visited[row * x + column] = false;

} else {

finished = true;

}

}

}

接下来,让我们使用demo 测试一把这些思路与代码

2874a6c0c0c349c4cb99828928e21287.png

我们采用上图的马儿作为起始位置,来测试看看public class HorseChessboard {

//省略其他关键性代码....

public static void main(String[] args) {

System.out.println("骑士周游算法,开始运行~~");

//测试骑士周游算法是否正确

x = 6;

y = 6;

int row = 4; //马儿初始位置的行,从1开始编号

int column = 3; //马儿初始位置的列,从1开始编号

//创建棋盘

int[][] chessboard = new int[x][y];

visited = new boolean[x * y];//初始值都是false

//测试一下耗时

long start = System.currentTimeMillis();

traversalChessboard(chessboard, row - 1, column - 1, 1);

long end = System.currentTimeMillis();

System.out.println("共耗时: " + (end - start) + " 毫秒");

//输出棋盘的最后情况

for(int[] rows : chessboard) {

for(int step: rows) {

System.out.print(step + "\t");

}

System.out.println();

}

}

}

运行结果如下:

骑士周游算法,开始运行~~

共耗时: 40 毫秒

08 03 10 29 32 05

17 28 07 04 11 30

02 09 18 31 06 33

27 16 01 20 23 12

36 19 14 25 34 21

15 26 35 22 13 24

三、使用贪心思想进行优化

利用贪心算法的思想,对下一步的所有集合的数目, 进行非递减排序

什么是非递减?

递增的情况是:1、2、3、4、5、6、7、8、9

递减的情况是:9、8、7、6、5、4、3、2、1

非递增的情况是:9、8、7、6、5、5、4、3、2、1

非递减的情况是:1、2、2、3、3、4、4、5、6、7

目的:使马儿走的下一步是下一步集合中可选性最少的,减少回溯可能性public class HorseChessboard {

//省略其他关键性代码....

//根据当前这个一步的所有的下一步的选择位置,进行非递减排序, 减少回溯的次数

public static void sort(ArrayList ps) {

ps.sort(new Comparator() {

@Override

public int compare(Point o1, Point o2) {

// TODO Auto-generated method stub

//获取到o1的下一步的所有位置个数

int count1 = next(o1).size();

//获取到o2的下一步的所有位置个数

int count2 = next(o2).size();

if(count1 < count2) {

return -1;

} else if (count1 == count2) {

return 0;

} else {

return 1;

}

}

});

}

}

那么怎么使用呢,我们在算法里进行排序优化public class HorseChessboard {

//省略其他关键性代码....

/**

* 完成骑士周游问题的算法

* @param chessboard 棋盘

* @param row 马儿当前的位置的行 从0开始

* @param column 马儿当前的位置的列 从0开始

* @param step 是第几步 ,初始位置就是第1步

*/

public static void traversalChessboard(int[][] chessboard, int row, int column, int step) {

//标记当前棋盘执行的是第几步

chessboard[row][column] = step;

//row = 3 X = 6 column = 3 = 3 * 6 + 3 = 21 -1 = 20

visited[row * x + column] = true; //标记该位置已经访问

//获取当前位置可以走的下一个位置的集合

ArrayList ps = next(new Point(column, row));

//对ps进行排序,排序的规则就是对ps的所有的Point对象的下一步的位置的数目,进行非递减排序

sort(ps);

//遍历 ps

while(!ps.isEmpty()) {

Point p = ps.remove(0);//取出下一个可以走的位置

//判断该点是否已经访问过

if(!visited[p.y * X + p.x]) {//说明还没有访问过

traversalChessboard(chessboard, p.y, p.x, step + 1);

}

}

}

}public class HorseChessboard {

//省略其他关键性代码....

public static void main(String[] args) {

System.out.println("骑士周游算法,开始运行~~");

//测试骑士周游算法是否正确

x = 6;

y = 6;

int row = 4; //马儿初始位置的行,从1开始编号

int column = 3; //马儿初始位置的列,从1开始编号

//创建棋盘

int[][] chessboard = new int[x][y];

visited = new boolean[x * y];//初始值都是false

//测试一下耗时

long start = System.currentTimeMillis();

traversalChessboard(chessboard, row - 1, column - 1, 1);

long end = System.currentTimeMillis();

System.out.println("共耗时: " + (end - start) + " 毫秒");

//输出棋盘的最后情况

for(int[] rows : chessboard) {

for(int step: rows) {

System.out.print(step + "t");

}

System.out.println();

}

}

}

运行结果如下:

骑士周游算法,开始运行~~

共耗时: 9 毫秒

08 03 10 29 32 05

17 28 07 04 11 30

02 09 18 31 06 33

27 16 01 20 23 12

36 19 14 25 34 21

15 26 35 22 13 24

从40毫秒 到9毫秒 这个速度还是很客观的,相比之前的算法更优一些

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

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

相关文章

app engine_App Engine中的Google Services身份验证,第2部分

app engine在本教程的第一部分中&#xff0c; 我介绍了如何使用OAuth进行Google API服务的访问/身份验证。 不幸的是&#xff0c;正如我稍后发现的那样&#xff0c;我使用的方法是OAuth 1.0&#xff0c;显然现在Google正式弃用了OAuth 1.0&#xff0c;改用OAuth 2.0版本。 显然…

Django知识总结(一)

壹 ● 有关http协议 一 ● 全称 超文本传输协议(HyperText Transfer Protocol) 二 ● 协议 双方遵循的规范 http协议是属于应用层的协议(还有ftp, smtp等), 即浏览器请求消息和服务器响应消息的一系列规则 三 ● http协议的特性 http是无状态、无连接的协议(stateless, connect…

java数组使用实验报告_JAVA数组与类的定义-java实验报告

JAVA数组与类的定义-java实验报告JAVA数组与类的定义-java实验报告、实验目的与要求1、 熟悉Java类、对象和方法的一般操作练习等。2、 熟悉数组等的定义和使用。二、实验内容及步骤(包括源程序和运行结果截图)1. 编写Java小应用程序&#xff0c;程序中自定义一个方法&#xff…

JPA 2.1和Java EE 7中的JPQL增强功能(第1部分– JOIN ON)

Java EE 7已经存在了几年&#xff0c;它提供了一些非常有用且期待已久的功能&#xff0c;例如实体图以及对存储过程和结果映射的更好支持。 有关概述&#xff0c;请参阅Thorben Janssen的博客文章 。 但是&#xff0c;我想添加有关JPA查询语言功能的更详细的摘要。 在JPQL和Cri…

mysql+if+x+mod+2_Windows 下 MantisBT 2.X + Apache 2.4 + PHP 7 + MySQL 5.7 的环境配置

Apache 2.4.25~ Visual C Redistributable for Visual Studio 2015PHP 7.1.3~ mod_fcgid-2.3.9Mantisbt-2.2.1MySQL Database 5.7.17~ NET Framework 3.5安装 Apache前期准备1.若计算机已安装了 Apache2.4 以前的版本&#xff0c;请自行卸载并删除安装目录。2.以管理员身份运行…

ASP.NET MVC ActionMethodSelectorAttribute 以及HttpGet等Action特性

一、ActionMethodSelectorAttribute 其是一个抽象类&#xff0c;继承自Attribute&#xff0c;子类有NonActionAttribute、HttpGetAttribute、HttpPostAttribute、HttpPutAttribute、HttpDeleteAttribute、HttpPatchAttribute、HttpHeadAttribute、HttpOptionsAttribute和Accept…

java 中map_Java中Map集合

1. Java中Map集合1. Map中value可以重复&#xff0c;key不能重复。对于重复的key值来说&#xff0c;后放置的值对覆盖前放置的值。import java.util.HashMap;public class MapTest1{public static void main(String[] args){HashMap map new HashMap();map.put("a",…

如何在Java中对文件进行模式匹配和显示相邻行

最近&#xff0c;我们在jOOλ0.9.9中发布了有关超棒的窗口函数支持的文章 &#xff0c;我相信这是对我们所做的库的最佳补充。 今天&#xff0c;我们将在一个用例中研究窗口函数的出色应用&#xff0c;该用例受到以下堆栈溢出问题Sean Nguyen的启发&#xff1a; 如何从Java 8…

64位内核第二讲,进程保护之对象钩子

64位内核第二讲,进程保护. 一丶什么是保护. 什么是保护. 比如我们安装了xxx杀毒软件.那么此时你用任务管理器关闭.是关闭不了的.原因是内核已经做了保护. 那么去掉保护的前提就是你要给自己的软件做保护. 比如我们给计算器做保护. 例如下图. 做保护.以前的病毒作者.都是想要退出…

java 类 request_java普通类得到request对象

使用拦截器import java.io.IOException;import javax.servlet.Filter;import javax.servlet.FilterChain;import javax.servlet.FilterConfig;import javax.servlet.ServletException;import javax.servlet.ServletRequest;import javax.servlet.ServletResponse;import javax.…

Xamarin.Forms Button长按事件

Xamarin.Forms Button长按事件 在平时的开发中&#xff0c;我们经常遇到需要Button能够拥有长按事件&#xff0c;但是在Xamarin.Forms中Button并没有该事件&#xff0c; 此时我们如何来实现呢&#xff1f; 我们知道在Xamarin.Forms中可以通过CustomRenderer来根据不同平台各自处…

java对象写入文件_将Java对象写入文件中

Java对象序列化 首先介绍一下对象序列化的目标:对象序列化的目标是将对象保存到磁盘中,或允许在网络中直接传输对象。 一、序列化的含义和意义: 序列化机制使得对象可以脱离程序的运行而独立存在。 对象的序列化指将一个Java对象写入IO流中,与此对应的反是,对象的反序列化…

jpql hql_无需部署即可测试JPQL / HQL

jpql hql您是否曾经想在不完全部署应用程序的情况下测试JPQL / HQL&#xff1f; 我们今天在这里看到的是适用于任何JPA实现的简单解决方案&#xff1a;Hibernate&#xff0c;OpenJPA&#xff0c;EclipseLink等。 这篇文章中找到的基本源代码来自本书&#xff1a;“ Pro JPA 2&a…

eclipse 代码上传github 笔记

第一步 先share project 如图所示 第二步 如果所示 第三步 点击 下面的create 然后点击完成 第四步提交 第五步&#xff1a; 第六步&#xff1a; 转载于:https://www.cnblogs.com/a8457013/p/8410471.html

java private 对象_[Java笔记]类的所有构造器都是private权限,就一定没有办法实例化它的对象了么?...

笔者以前学过C语言。众所周知&#xff0c;C也是一门面向对象程序设计语言。还记得当时在大学的时候&#xff0c;老师讲过这样的话&#xff1a;类的构造函数不应该设置成private权限&#xff0c;这样的话还怎么去实例化类的对象&#xff1f;当时也信以为然。现在在学java&#x…

[Usaco2008 Feb]Eating Together麻烦的聚餐

Description 为了避免餐厅过分拥挤&#xff0c;FJ要求奶牛们分3批就餐。每天晚饭前&#xff0c;奶牛们都会在餐厅前排队入内&#xff0c;按FJ的设想所有第3批就餐的奶牛排在队尾&#xff0c;队伍的前端由设定为第1批就餐的奶牛占据&#xff0c;中间的位置就归第2批就餐的奶牛了…

Keycloak SSO集成到jBPM和Drools Workbench中

介绍 单一登录&#xff08;SSO&#xff09;和相关令牌交换机制正在成为Web上不同环境中进行身份验证和授权的最常见方案&#xff0c;尤其是在迁移到云中时。 本文讨论了Keycloak与jBPM或Drools应用程序的集成&#xff0c;以便使用Keycloak上提供的所有功能。 Keycloak是用于浏…

接口 java性能_接口测试性能测试

接口测试 接口测试是测试系统组件间接口的一种测试&#xff0c;主要用于检测外部系统与系统之间以及内部各个子系统之间的交互点。测试的重点是要检查数据的交换&#xff0c;传递和控制管理过程&#xff0c;以及系统间的相互逻辑依赖关系等。 原理 通过测试程序模拟客户端向服务…

C 标准库 - string.h

C 标准库 - string.h This header file defines several functions to manipulate C strings and arrays.string .h 头文件定义了一个变量类型、一个宏和各种操作字符数组的函数。库变量 size_t Unsigned integral type (type )这是无符号整数类型&#xff0c;它是 sizeof 关键…

Redis 小结

一、redis简介 redis是一款基于C语言编写的&#xff0c;开源的非关系型数据库&#xff0c;由于其卓越的数据处理机制&#xff08;按照规则&#xff0c;将常用的部分数据放置缓存&#xff0c;其余数据序列化到硬盘&#xff09;&#xff0c;大家也通常将其当做缓存服务器来使用。…