当前位置: 首页 > news >正文

【C++算法】dfs深度优先搜索(上) ——【全面深度剖析+经典例题展示】

💃🏼 本人简介:男
👶🏼 年龄:18
📕 ps:七八天没更新了欸,这几天刚搞完元宇宙,上午一直练🚗,下午背四级单词和刷题来着,还在忙一些学弟学妹录制视频和准备开学一些事,一直没空出时间来,等 20号练完车,也马上开学了QAQ。不过今天倒是空出来一些时间,恰好这几天学到了dfs,原理和例题都很棒,谨以此篇作为学后的回顾总结!

文章目录

  • 1. dfs算法原理
    • 1.1 dfs思想
    • 1.2 与递归区别
    • 1.3 举例说明
  • 2. 经典例题——迷宫游戏
    • 2.1 题干信息
    • 2.2 整体思路
    • 2.3 细分拆解
      • ①判断迷宫终点,记录所走路径
      • ②完善搜索与回溯,处理数组边界
      • ③找寻迷宫起点,打印结束路径
    • 2.4 总体代码展示
    • 2.5 测试样例
    • 2.6 代码优化
  • 最后,感谢大家支持u (^ _ ^)

1. dfs算法原理

1.1 dfs思想

  • 深度优先搜索,简称dfs,简单讲就是一个搜索算法。
  • 深搜是按照深度优先的方式进行搜索,通俗来讲就是一条路走到黑不撞南墙不回头
  • 注意:这里的搜索并不是我们平时在文件上或网络上查找信息,而是通过一种穷举的方式,把所有可行的方案都列举出来,不断去尝试,直到找到问题的解。
  • 具体来讲,dfs可以将“问题状态空间”看做一棵搜索树,深度优先就是从树根一直往下搜,遇到不可解就回溯,往其它方向继续向下扩展,像子集和和全排列问题,还有N皇后问题都可以深度优先搜索算法解决,它是一种暴力解决NP问题的非常直观的方法。
  • 总的来说:DFS 用于找所有解的问题,它的空间效率高,而且找到的不一定是最优解,必须记录并完成整个搜索,故一般情况下,深搜需要非常高效的剪枝(剪枝的概念请百度)。

1.2 与递归区别

  • 深搜是一种算法,注重的是思想;而递归是一种基于编程语言的实现方式。
  • 深搜可以用递归实现,也就是说递归是我们用计算机编程语言实现深搜算法的手段。

1.3 举例说明

如下图,灰色代表墙壁,绿色代表起点,红色代表终点,规定每次只能走一步,且只能往下或右走。求一条绿色到红色的最短路径。例子来源于这里

在这里插入图片描述

用dfs来讲就是,先从绿点开始找准一个方向,并沿这个方向一直遍历,如果遇到障碍物不能继续遍历就回溯,返回上一个节点,直到找到终点为止。请添加图片描述

2. 经典例题——迷宫游戏

都学了这么多了。我们不妨来玩一个迷宫游戏巩固一下所学的算法!【迷宫如图下所示】
在这里插入图片描述

最短的解法如下图所示【大家答对了嘛】 在这里插入图片描述

2.1 题干信息

  • 我们用一个二维字符数组来表示图画的迷宫。
S**.
....
***T
  • 其中S表示起点,T表示终点,*表示墙壁,.表示平地。你需要从S出发走到T,每次只能向上下左右相邻的位置移动一位,不能走出地图,也不能穿过墙壁,每个点只能通过一次。用x表示你所要走的路线。

2.2 整体思路

  • 我们从起点S开始,每走一步需要对上下左右一个方向一个方向地尝试,如果沿着某个方向不能走到终点,我们就要原路返回,继续尝试其他方向,直到走出迷宫。这是一种最朴素的走迷宫方式,虽然效率也许比较低,但如果迷宫有解,就一定能走出终点。
  • 上面说的这种走法,就对应着今天学习的dfs算法。首先找到起点s,走到每个点时,按照左、下、右、上的顺序尝试。每走到下一个点以后,我们把这个点当做起点S,继续按顺序尝试。如果某个点上下左右四个方向都尝试过,便回到走到这个点之前的点,这一步我们称之为回溯。继续尝试其他方向。直到所有点都尝试过上下左右四个方向。
  • 这就好比你自己去走这个迷宫,你也要一个方向一个方向的尝试着走,如果这条路不行就回头,尝试下一条路,dfs 的思想和我们直观的想法很类似。只不过,接下来我们需要用程序来完成这个过程。

2.3 细分拆解

第一步前的输入地图和变量设置,就不详细讲了,直接看代码即可

#include<iostream>
#include<stdio.h>
using namespace std;
int n, m;
char pos[150][150];	   //判断走没走过
bool trace[150][150];  //显示路径int main() {//输入地图cin >> n >> m;for (int i = 1; i <= n; i++) {for (int j = 1; j <= m; j++) {cin >> pos[i][j];}}return 0;
}

①判断迷宫终点,记录所走路径

  • 首先确定边界条件,当走到字符T时,我们找到了终点,从而结束搜索。所以边界条件判断为pos[x][y] == 'T'
  • 其次,为了防止走回头路,我们需要标记当前这个路径已走过,即当前这个点已走过,所以我们需要用trace[x][y]数组来做标记,为了显示出路径,走过的点我们用字符x表示。
bool dfs(int x, int y) {if (pos[x][y] == 'T') { //找到终点,返回truereturn true;}trace[x][y] = 1;		//若找不到,则trace数组标记为1表示已走过pos[x][y] = 'x';		//用pos显示最后的路径
}

②完善搜索与回溯,处理数组边界

  • 结束操作处理好后,就要开始真正的搜索了。假设现在我们坐标为(x, y),分别遍历该坐标的上下左右位置,选择好依次进行方向的顺序后,一个方向一个方向进行访问,如果某一方向能走到终点,则返回true
  • 在上下左右遍历时,我们要考虑数组元素是否越界,此时我们就需要一个bool类型的check_in()函数进行判断。
  • 注意:判断移动后位置能走的3个条件【缺一不可】
    • ①没越界,在地图内;
    • ②这个位置不是障碍物*,可以走到;
    • ③该位置之前没走过
bool check_in(int x, int y) {	//	判断数组是否越界return (x > 0 && x <= n && y > 0 && y <= m); //这里表示的是如果()里为真,则返回true,否则返回false
}bool dfs(int x, int y) {if (pos[x][y] == 'T') { //找到终点,返回truereturn true;}trace[x][y] = 1;		//若上下左右都找不到,则trace数组标记为1表示已走过pos[x][y] = 'x';		//用pos显示最后的路径int tx = x - 1, ty = y; //假设先往上走if (check_in(tx, ty) && pos[tx][ty] != '*' && !trace[tx][ty]) { //能移动到该位置的条件有三个:①没越界,在地图内; ②这个位置不是障碍物*,可以走到; ③该位置之前没走过if (dfs(tx, ty)) {	//对移动后位置进行判断是不是终点,如果是,返回true,如果不是,在对其上下左右判断。return true;}}tx = x, ty = y - 1; //如果往上走行不通,则选择向左走if (check_in(tx, ty) && pos[tx][ty] != '*' && !trace[tx][ty]) {if (dfs(tx, ty)) {return true;}}tx = x + 1, ty = y; //如果往左走行不通,则选择向下走if (check_in(tx, ty) && pos[tx][ty] != '*' && !trace[tx][ty]) {if (dfs(tx, ty)) {return true;}}tx = x , ty = y + 1; //如果往下走行不通,则选择向右走if (check_in(tx, ty) && pos[tx][ty] != '*' && !trace[tx][ty]) {if (dfs(tx, ty)) {return true;}}pos[x][y] = '.';	//	如果一个位置的上下左右都走不了,则取消该位置的路径进行回溯,回溯过程把之前已标记的'x'改回'.'trace[x][y] = 0;//只找可行路线的话,trace可改可不改。但如果找全部解,则需要恢复return false;
}

大家有没有发现判断上下左右是否可行时,主题代码是不是都是一样的欸?所以大家可以想一下,能怎么去优化一下嘛,在这里我卖个关子,咱们后面马上讲!

③找寻迷宫起点,打印结束路径

  • 我们费心费力地把迷宫主体的dfs的函数写完了,但我们该从哪开始呢?结束条件如何设置呢?
int main() {//输入地图cin >> n >> m;for (int i = 1; i <= n; i++) {for (int j = 1; j <= m; j++) {cin >> pos[i][j];}}cout << "----------------------------------------" << endl;//找寻起点int x , y ; //定义x,y用于保存迷宫起点时的位置for (int i = 1; i <= n; i++) {for (int j = 1; j <= m; j++) {if (pos[i][j] == 'S') {x = i, y = j;}}}if (dfs(x, y)) { //如果能找到终点,则打印迷宫显示其路径cout << "鼠鼠我欸,已到达终点啦,路线如下: " << endl;for (int i = 1; i <= n; i++) {for (int j = 1; j <= m; j++) {cout << pos[i][j];} cout << endl;}}else {cout << "鼠鼠我欸,走不出去啦awa" << endl;}return 0;
}

2.4 总体代码展示

#include<iostream>
#include<stdio.h>
using namespace std;int n, m;
char pos[150][150];	   //判断走没走过
bool trace[150][150];  //显示路径bool check_in(int x, int y) {	//	判断数组是否越界return (x > 0 && x <= n && y > 0 && y <= m); //这里表示的是如果()里为真,则返回true,否则返回false
}bool dfs(int x, int y) {if (pos[x][y] == 'T') { //找到终点,返回truereturn true;}trace[x][y] = 1;		//若上下左右都找不到,则trace数组标记为1表示已走过pos[x][y] = 'x';		//用pos显示最后的路径int tx = x - 1, ty = y; //假设先往上走if (check_in(tx, ty) && pos[tx][ty] != '*' && !trace[tx][ty]) { //能移动到该位置的条件有三个:①没越界,在地图内; ②这个位置不是障碍物*,可以走到; ③该位置之前没走过if (dfs(tx, ty)) {	//对移动后位置进行判断是不是终点,如果是,返回true,如果不是,在对其上下左右判断。return true;}}tx = x, ty = y - 1; //如果往上走行不通,则选择向左走if (check_in(tx, ty) && pos[tx][ty] != '*' && !trace[tx][ty]) {if (dfs(tx, ty)) {return true;}}tx = x + 1, ty = y; //如果往左走行不通,则选择向下走if (check_in(tx, ty) && pos[tx][ty] != '*' && !trace[tx][ty]) {if (dfs(tx, ty)) {return true;}}tx = x , ty = y + 1; //如果往下走行不通,则选择向右走if (check_in(tx, ty) && pos[tx][ty] != '*' && !trace[tx][ty]) {if (dfs(tx, ty)) {return true;}}pos[x][y] = '.';	//	如果一个位置的上下左右都走不了,则取消该位置的路径进行回溯,回溯过程把之前已标记的'x'改回'.'trace[x][y] = 0;//只找可行路线的话,trace可改可不改。但如果找全部解,则需要恢复return false;
}
int main() {//输入地图cin >> n >> m;for (int i = 1; i <= n; i++) {for (int j = 1; j <= m; j++) {cin >> pos[i][j];}}cout << "----------------------------------------" << endl;//找寻起点int x , y ; //定义x,y用于保存迷宫起点时的位置for (int i = 1; i <= n; i++) {for (int j = 1; j <= m; j++) {if (pos[i][j] == 'S') {x = i, y = j;}}}if (dfs(x, y)) { //如果能找到终点,则打印迷宫显示其路径cout << "鼠鼠我欸,已到达终点啦,路线如下: " << endl;for (int i = 1; i <= n; i++) {for (int j = 1; j <= m; j++) {cout << pos[i][j];} cout << endl;}}else {cout << "鼠鼠我欸,走不出去啦awa" << endl;}return 0;
}

2.5 测试样例

在这里插入图片描述

2.6 代码优化

  • 前面提到,我们在对下一位置进行上下左右判断时,需要写四个主体相同的代码。为了减少代码量,我们不妨写一个循环,用一个二维数组依次表示四个方向,进而进行判断。
int dir[4][2] = { { -1 , 0 } , { 0 , -1 } , { 1 ,  0 } , { 0 , 1 } };
//	按逆时针依次表示     向上	      向左		 向下	         向右	
//第一个数表示x(行)变化,第二个表示y(列)变化
bool dfs(int x, int y) {if (dfs(x, y) == 'T') {return true;}trace[x][y] = 1;pos[x][y] = 'x';for (int i = 1; i <= 4; i++) {  //1、2、3、4依次表示上、左、下、右int tx = x + dir[i][0]; //表示x加上第几个方向的第1个数,即行变化,int ty = y + dir[i][1];  //表示x加上第几个方向的第2个数,即列变化,if (check_in(tx, ty) && pos[tx][ty] != '*' && !trace[tx][ty]) {if (dfs(tx, ty)) {return true;}}}pos[x][y] = '.';	//	如果一个位置的上下左右都走不了,则取消该位置的路径进行回溯,回溯过程把之前已标记的'x'改回'.'trace[x][y] = 0;//只找可行路线的话,trace可改可不改。但如果找全部解,则需要恢复
}

优化后代码

#include<iostream>
#include<stdio.h>
using namespace std;int n, m;
char pos[150][150];	   //判断走没走过
bool trace[150][150];  //显示路径int dir[4][2] = { { -1 , 0 } , { 0 , -1 } , { 1 ,  0 } , { 0 , 1 } };
//	按逆时针依次表示     向上	      向左		 向下	         向右	
//第一个数表示x(行)变化,第二个表示y(列)变化bool check_in(int x, int y) {	//	判断数组是否越界return x > 0 && x <= n && y > 0 && y <= m; //这里表示的是如果()里为真,则返回true,否则返回false
}bool dfs(int x, int y) {if (dfs(x, y) == 'T') {return true;}trace[x][y] = 1;pos[x][y] = 'x';for (int i = 1; i <= 4; i++) {  //1、2、3、4依次表示上、左、下、右int tx = x + dir[i][0]; //表示x加上第几个方向的第1个数,即行变化,int ty = y + dir[i][1];  //表示x加上第几个方向的第2个数,即列变化,if (check_in(tx, ty) && pos[tx][ty] != '*' && !trace[tx][ty]) {if (dfs(tx, ty)) {return true;}}}pos[x][y] = '.';	//	如果一个位置的上下左右都走不了,则取消该位置的路径进行回溯,回溯过程把之前已标记的'x'改回'.'trace[x][y] = 0;//只找可行路线的话,trace可改可不改。但如果找全部解,则需要恢复}int main() {//输入地图cin >> n >> m;for (int i = 1; i <= n; i++) {for (int j = 1; j <= m; j++) {cin >> pos[i][j];}}cout << "----------------------------------------" << endl;//找寻起点int x , y ; //定义x,y用于保存迷宫起点时的位置for (int i = 1; i <= n; i++) {for (int j = 1; j <= m; j++) {if (pos[i][j] == 'S') {x = i, y = j;}}}if (dfs(x, y)) { //如果能找到终点,则打印迷宫显示其路径cout << "鼠鼠我欸,已到达终点啦,路线如下: " << endl;for (int i = 1; i <= n; i++) {for (int j = 1; j <= m; j++) {cout << pos[i][j];} cout << endl;}}else {cout << "鼠鼠我欸,走不出去啦awa" << endl;}return 0;
}

最后,感谢大家支持u (^ _ ^)

如果感觉这篇文章对你有帮助的话,不妨三连支持下,十分感谢(✪ω✪)。

printf("点个赞吧*^*");
cout << "收藏一下叭o_o";
System.out.println("评论一下吧^_^");
print("关注一下叭0-0")

相关文章:

【C++算法】dfs深度优先搜索(上) ——【全面深度剖析+经典例题展示】

&#x1f483;&#x1f3fc; 本人简介&#xff1a;男 &#x1f476;&#x1f3fc; 年龄&#xff1a;18 &#x1f4d5; ps:七八天没更新了欸&#xff0c;这几天刚搞完元宇宙&#xff0c;上午一直练&#x1f697;&#xff0c;下午背四级单词和刷题来着&#xff0c;还在忙一些学弟…...

总结高频率Vue面试题

目录 什么是三次握手&#xff1f; 什么是四次挥手&#xff1f;&#xff08;close触发&#xff09; 什么是VUEX&#xff1f; 什么是同源----跨域&#xff1f; 什么是Promise&#xff1f; 什么是fexl布局&#xff1f; 数据类型 什么是深浅拷贝&#xff1f; 什么是懒加载&…...

IP协议详解

目录 前言&#xff1a; IP协议 提出问题 解决方案 地址管理 子网掩码 路由选择 小结&#xff1a; 前言&#xff1a; IP协议作为网络层知名协议。当数据经过传输层使用TCP或者UDP对数据进行封装&#xff0c;然后当数据到达网络层&#xff0c;基于TCP或UDP数据包继续进行…...

webpack5 基础配置

在开发中&#xff0c;我们会使用 vue、react、less、scss等语法进行开发项目&#xff0c;但是浏览器只能识别 js、css&#xff0c;或者说在js中使用了es6中的import 导入 这时候也需要打包工具去转换成浏览器可以识别的语句。 一、使用webpack 1.初始化package.json npm i…...

IDEA入门安装使用教程

一、背景 作为一个Java开发者&#xff0c;有非常多编辑工具供我们选择&#xff0c;比如Eclipse、IntelliJ IDEA、NetBeans、Visual Studio Code、Sublime Text等等&#xff0c;这些有免费也有收费的&#xff0c;但是就目前市场占比来说普遍使用Eclipse和IntelliJ IDEA这两款主…...

Lambda表达式使用及详解

一 Lambda表达式的简介 Lambda表达式&#xff08;闭包&#xff09;&#xff1a;java8的新特性&#xff0c;lambda运行将函数作为一个方法的参数&#xff0c;也就是函数作为参数传递到方法中。使用lambda表达式可以让代码更加简洁。 Lambda表达式的使用场景&#xff1a;用以简…...

JAVA练习52-打家劫舍

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 目录 前言 一、题目-打家劫舍 1.题目描述 2.思路与代码 2.1 思路 2.2 代码 总结 前言 提示&#xff1a;这里可以添加本文要记录的大概内容&#xff1a; 2月16日练习内容 提…...

简单谈一谈幂等测试

1、什么是幂等测试 幂等是一个抽象的概念&#xff0c;在编程中一个幂等操作的特点是其任意多次执行所产生的影响均与一次执行的影响相同&#xff0c;即多次调用方法或者接口不会改变业务状态&#xff0c;可以保证重复调用的结果和单次调用的结果一致。幂等测试&#xff0c;则主…...

typescript复习笔记

数组类型-限定每一项的类型 //写法一 const arrNumber: number[] [1, 2, 3] const arrString: string[] [a, b, c] //写法二 const arrNumber2: Array<number> [1, 2, 3] const arrString2: Array<string> [a, b, c]联合类型 符号是 | //数组可以存放字符串或…...

webstorm开发electron,调试主进程方案

官网教程地址&#xff1a;https://www.electronjs.org/zh/docs/latest/tutorial/debugging-main-process 我只能说官网太看得起人了&#xff0c;整这么简易的教程…… 命令行开关 第一步还是要按要求在我们的package.json里加上端口监听&#xff1a;–inspect5858 我的命令…...

2W字正则表达式基础知识总结,这一篇就够了!!(含前端常用案例,建议收藏)

正则表达式 (Regular Expression&#xff0c;简称 RE 或 regexp ) 是一种文本模式&#xff0c;包括普通字符&#xff08;例如&#xff0c;a 到 z 之间的字母&#xff09;和特殊字符&#xff08;称为"元字符"&#xff09;正则表达式使用单个字符串来描述、匹配一系列匹…...

自学web前端觉得好难,可能你遇到了这些困境

好多人跟我说上学的时候也学过前端&#xff0c;毕业了想从事web前端开发的工作&#xff0c;但自学起来好难&#xff0c;快要放弃了&#xff0c;所以我总结了一些大家遇到的困境&#xff0c;希望对你会有所帮助。 目录 1. 意志是否坚定 2. 没有找到合适自己的老师 3. 为了找…...

ASEMI中低压MOS管18N20参数,18N20封装,18N20尺寸

编辑-Z ASEMI中低压MOS管18N20参数&#xff1a; 型号&#xff1a;18N20 漏极-源极电压&#xff08;VDS&#xff09;&#xff1a;200V 栅源电压&#xff08;VGS&#xff09;&#xff1a;30V 漏极电流&#xff08;ID&#xff09;&#xff1a;18A 功耗&#xff08;PD&#x…...

[NetBackup]客户端安装后server无法连通client

client name处填写客户端主机名&#xff0c;server to use for backups and restores处填写server端名字&#xff0c;与hosts文件内保持一致&#xff1b;source client for restores处填写client主机名&#xff0c;与server端hosts文件中保持一致&#xff0c;与主机实际名称保持…...

黑马Java后端项目实战--在线聊天交友

【课程简介】 越来越多的系统都有消息推送的功能&#xff0c;如聊天室、邮件推送、系统消息推送等&#xff1b; 要实现消息推送就需要服务端在数据有变化时主动推送消息给客户端&#xff0c;本次课程将带大家使用websocket实现消息推送。 【主讲内容】 1.方法&#xff1a;如…...

【实战系列 2】Yapi接口管理平台Getshell-Linux后门权限维持与痕迹清除

文章目录 前言一、网站主页到Getshell二、SSH软链接后门三、Linux权限维持 --隐藏踪迹3.1 隐藏远程SSH登陆记录3.2、ssh软链接后门连接失败的原因以及解决办法3.3、隐藏踪迹-痕迹清楚3.3.1、隐藏历史操作命令3.3.2、隐藏文件/文件夹3.3.3、修改文件时间戳3.3.4、隐藏权限3.3.5、…...

设计模式之抽象工厂模式(C++)

作者&#xff1a;翟天保Steven 版权声明&#xff1a;著作权归作者所有&#xff0c;商业转载请联系作者获得授权&#xff0c;非商业转载请注明出处 一、抽象工厂模式是什么&#xff1f; 抽象工厂模式是一种创建型的软件设计模式&#xff0c;该模式相当于升级版的工厂模式。 如果…...

Kotlin新手教程一(Kotlin简介及环境搭建)

目录一、 什么是Kotlin&#xff1f;二、为什么要使用Kotlin&#xff1f;三、使用IntelliJ IDEA搭建Kotlin四、Kotlin使用命令行编译一、 什么是Kotlin&#xff1f; Kotlin 是一种在 Java 虚拟机上运行的静态类型编程语言&#xff0c;它也可以被编译成为 JavaScript 源代码&…...

【虚拟仿真】Unity3D打包WEBGL实现全屏切换

推荐阅读 CSDN主页GitHub开源地址Unity3D插件分享简书地址我的个人博客 大家好&#xff0c;我是佛系工程师☆恬静的小魔龙☆&#xff0c;不定时更新Unity开发技巧&#xff0c;觉得有用记得一键三连哦。 一、前言 今天实现Unity3D打包WEBGL后实现按钮点击全屏和退出 全屏的实现…...

java对象内存结构分析与大小计算

java对象内存结构Java对象保存在堆中时&#xff0c;由三部分组成&#xff1a;对象头&#xff08;object header&#xff09;&#xff1a;包括了关于堆对象的布局、类型、GC状态、同步状态和标识哈希码的基本信息。所有java对象都有一个共同的对象头格实例数据&#xff08;Insta…...

RabbitMQ学习(七):交换器

〇、前言在之前的内容中&#xff0c;我们创建了一个工作队列。我们假设的是工作队列背后&#xff0c;每个任务都恰好交付给一个消 费者(工作进程)。在今天的内容中&#xff0c;我们将做一些完全不同的事情——我们将消息传达给多个消费者。这种模式 称为 “发布/订阅”。为了说…...

cmd命令大全

文章目录变量输入输出逻辑命令符控制语句函数注释变量 在批处理中&#xff0c;变量全部是弱类型的&#xff0c;通常可以当做字符串处理 1.初始化定义 set varthis a var 2.获取变量值 %var% 3.链接 set varcat%var1%%var2% 4.截取 %var:~n,m% n是起点&#xff0c;m是长度&…...

Git的使用方法(保姆级)

一、安装git二、创建凭据 ①打开电脑的凭据管理器git:https://gitee.com是固定写法用户名、密码是你创建gitee的用户名、密码三、在gitee中创建一个仓库四、项目提交到仓库的方法①选择一个项目交由git管理按照步骤一中召唤小黑窗口输入 git init 就可以出现.git文件夹②右键选…...

TypeScript 学习之泛型

泛型使用 组件不仅能够支持当前的数据类型&#xff0c;同时也能支持未来的数据类型。就需要使用泛型。使用泛型就不会丢失类型信息&#xff0c;使用any会丢失类型信息。 function identity<T>(arg: T): T {return arg; }identity 添加了类型变量T, T 捕获用户传入的类型…...

新手学习node.js基础,node.js安装过程,node.js运行环境及javascript运行环境.

学习node.js1.什么是node.js?2.node.js中的javaScript运行环境3.node.js可以做什么&#xff1f;4. node.js学习思路5.node.js环境的安装6.如何在node.js中执行JavaScript代码1.什么是node.js? node.js是一个基于Chrome v8 引擎的JavaScript运行环境(后端) node.js官网 &…...

Maven的安装步骤(保姆级安装教程)

一、安装本地Maven 选择你需要的maven版本下载&#xff1a;官网下载传送门 我使用的是3.6.1版本&#xff1a;maven-3.6.1-bin.zip 二、安装 把下载好的maven压缩包解压到一个没有中文&#xff0c;空格或其他特殊字符的文件夹&#xff0c;如&#xff1a; 三、配置环境变量…...

Axure教程(一)——线框图与高保真原型图制作

前面我们学习了制作网页的技能&#xff0c;从这里开始我们来学习前端必备技能&#xff0c;就是用Axure来制作原型图&#xff0c;一方面我们能提前绘制出我们所需的页面&#xff0c;这在我们开发的时候能节省大量的时间&#xff0c;另一方面我们能通过给用户进行体验从而能够发现…...

wholeaked:一款能够追责数据泄露的文件共享工具

关于wholeaked wholeaked是一款功能强大的文件共享工具&#xff0c;该工具基于go语言开发&#xff0c;可以帮助广大系统管理员和安全研究人员在组织发生数据泄露的时候&#xff0c;迅速找出数据泄露的“始作俑者”。 wholeaked可以获取被共享的文件信息以及接收人列表&#x…...

动态规划——股票问题全解

引入 股票问题是一类动态问题&#xff0c;我们需要对其状态进行判定分析来得出答案 但其实&#xff0c;我们只需要抓住两个点&#xff0c;持有和不持有&#xff0c;在这两种状态下分析问题会简单清晰许多 下面将会对各个问题进行分析讲解&#xff0c;来解释什么是持有和不持…...

想做游戏开发要深入c/c++还是c#?

根据题主描述提三点建议&#xff1a; 先选择一个语言、选择一个引擎能入行确保精通一个及已入行的情况下&#xff0c;技多不压身不必想日后的”退而求其次“&#xff0c;现在的事情还没有开始做就想以后&#xff0c;太过虚无及功利了 下面是这三点的详细说明&#xff1a; 【选…...

wordpress跳过短代码/广州市口碑seo推广外包

有时需引入外部字体&#xff0c;字体文件过大&#xff0c;页面加载很慢&#xff0c;故使用此方法压缩。 安装 npm install font-spider -g 使用 新建【font】目录&#xff0c;html文件&#xff0c;将项目里需要压缩的文字写入html&#xff1b;将字体文件放入目录&#xff1…...

选择美国网站/google下载官网

6.1 持久化简介 Android 系统中主要提供了三种方式用于简单地实现数据持久化功能&#xff0c;即文件存储、SharedPreference 存储以及数据库存储。当然&#xff0c;除了这三种方式之外&#xff0c;你还可以将数据保存在手机的 SD 卡中&#xff0c;不过使用文件、SharedPreferen…...

收不到 wordpress 邮件/百度订单售后电话

RDB文件格式一、Redis RDB文件二、解析RDB的高级算法2.1 Magic Number2.2 RDB 版本号2.3 操作码2.3.1 数据库选择器2.3.2 Resizeb信息2.3.3 辅助字段2.3.4 键值对key 到期时间戳值类型键值2.4 CRC64校验码三、编码方式3.1 Length Encoding 长度编码3.2 字符串编码3.2.1 长度前缀…...

如何建立网站链接/注册公司流程和费用

一、MNIST手写数字介绍 1、获取样本 手写数字的MNIST数据库可从此页面获得&#xff0c;其中包含60,000个示例的训练集以及10,000个示例的测试集。它是NIST提供的更大集合的子集。这些数字已经过尺寸标准化并以固定尺寸的图像为中心。 下载链接&#xff1a;http://yann.lecun.co…...

企业网站用视频做首页/今日竞彩足球最新比赛结果查询

1. 概述 本章主要讲解.net4.5如何实现多线程和异步处理的相关内容。 2. 主要内容 2.1 理解线程 ① 使用Thread类 public static class Program { public static void ThreadMethod() { for (int i 0; i < 10; i) { Console.WriteLine(“ThreadProc: {0}”, i); Thread.Slee…...

如何在百度举报网站/网络营销运营公司

1.java3d开发环境搭建 jdk(java development kit)安装java3d安装IDE安装(eclipse,idea,netbeans选择一种即可) 2.java3d开发引擎 JMEArdor3DXith3D 3.java3d原理 JAVA 3D从高层次为开发者提供对三维实体的创建、操纵和着色&#xff0c;使开发工作变得极为简单。同时&#…...