迷宫问题
🚀学习过算法程序设计的应该都学习过迷宫这个问题,迷宫问题主要设计的算法就是DFS-深度优先遍历和BFS-广度优先遍历。
🚀在一个二维数组中,元素为1的位置表示这个位置是墙,0表示有通路,迷宫的入口和出口都是0(否则不会有路径能出去),并且路径不唯一。例如下图:

🚀图中这个迷宫有两条路径,分别用粉色和蓝色标记了出来,明显粉色路径的长度是比蓝色路径要短的。
🚀BFS可以解决最短路径的原因是,BFS是像水波一样逐渐向外圈波及的,很明显最先波及到的通路就是最短路径。
🚀使用BFS算法的思想
一般的广度优先遍历都是采用队列完成的,每次取对头然后将其周围四个位置压到队列当中,然后pop掉对头,这样循环下去直到队列为空就停止。但是这种算法无法记录迷宫走过的路径,所以我才用vector来模拟队列来使用,就相当于对头的数据不pop掉,而是用一个下标来控制,现在走到哪个下标了,并且存储当前位置的结构体中多设置了一个变量prev,存储的是这个位置的上个位置在vector中的下标。这样在迷宫中走到终点的时候,返回这个vector,里面就有我们过的路径了。
🚀代码实现
struct path
{
int _x;
int _y;
int _prev; // 在模拟对列中的下标位置
path(int x,int y,int prev)
:_x(x)
,_y(y)
,_prev(prev)
{}
};
bool check(int i, int j, int map[][8], int row, int col)
{
if (i < 0 || j < 0 || i > row - 1 || j > col - 1)
return false;
if (map[i][j] == -1) //走过的位置被设置为-1
return false;
if (map[i][j] == 1)
return false;
return true;
}
vector<path> BFS(int map[][8], int row, int col)
{
vector<path> v;
v.push_back(path(0, 0, -1));
size_t index = 0;
int fx[4] = { 0,1,-1,0 };
int fy[4] = { 1,0,0,-1 };
int i = 0, j = 0;//当前位置的横纵坐标
while (index < v.size())
{
i = v[index]._x;
j = v[index]._y;
for (int k = 0; k < 4; k++)
{
int new_i = i + fx[k];
int new_j = j + fy[k];
if (check(new_i, new_j, map, row, col))
{
v.push_back(path(new_i, new_j, index));
map[new_i][new_j] = -1;
if (new_i == row - 1 && new_j == col - 1)
return v;
}
}
index++;
}
cout << "error" << endl;
return v;
}
int main()
{
int map[7][8] = {
{0,0,0,1,1,1,1,1},
{0,1,0,1,1,1,1,1},
{0,1,0,1,0,0,0,1},
{0,1,0,1,0,1,0,1},
{0,1,0,0,0,1,0,1},
{0,1,1,1,1,1,0,1},
{0,0,0,0,0,0,0,0}
};
vector<path> res = BFS(map, 7, 8);
int i = res.size() - 1;
while (i >= 0)
{
cout << "(" << res[i]._x << "," << res[i]._y << ")" << endl;
i = res[i]._prev;
}
}
🚀运行结果

🚀你会发现打印的结果是从终点走向起点的,我们可以对其做一下修改。使用递归的方式逆向打印出结果。
void Print(vector<path>& v, int index)
{
if (index == 0)
{
cout << "(" << v[index]._x << "," << v[index]._y << ")" << endl;
return;
}
Print(v, v[index]._prev);
cout << "(" << v[index]._x << "," << v[index]._y << ")" << endl;
}
🚀这样我们就能得到正向的路径了。

🚀BFS算法思想
深度优先搜索是,一条道走到黑,走不通再换另一条路,对于深度优先搜索,我们可以用栈来记录它的路径,每次进入程序后,先将当前位置压栈,再让他向上下左右去试探,值得注意的是要在最后进行弹栈处理,因为如果上下左右都我没有返回true表明从此位置出发是到不了终点的,说明此位置不在最终的路径当中,所以要弹栈。并且在开始的时候将此位置压栈后,要将此位置对应的数据改为-1,表明在后面的递归中不能往回走了(会造成死循环),并且在弹栈后要将此位置的值修改为0,这是因为这层函数栈帧已经结束,返回到上一层栈帧中,而返回到上一层栈帧的时候,这个位置是没有被访问的。
🚀代码实现
bool DFS(int map[][8], int row, int col, stack<_path>& st,int i,int j)
{
st.push(_path(i, j));
map[i][j] = -1;
if (i == row - 1 && j == col - 1)
return true;
if (check(i + 1, j, map, row, col))
if (DFS(map, row, col, st, i + 1, j))
return true;
if (check(i, j + 1, map, row, col))
if (DFS(map, row, col, st, i, j + 1))
return true;
if (check(i - 1, j, map, row, col))
if (DFS(map, row, col, st, i - 1, j))
return true;
if (check(i, j - 1, map, row, col))
if (DFS(map, row, col, st, i, j - 1))
return true;
map[i][j] = 0;
st.pop();
return false;
}
int main()
{
int map[7][8] = {
{0,0,0,1,1,1,1,1},
{0,1,0,1,1,1,1,1},
{0,1,0,1,0,0,0,1},
{0,1,0,1,0,1,0,1},
{0,1,0,0,0,1,0,1},
{0,1,1,1,1,1,0,1},
{0,0,0,0,0,0,0,0}
};
//vector<path> res = BFS(map, 7, 8);
//int i = res.size() - 1;
/*while (i >= 0)
{
cout << "(" << res[i]._x << "," << res[i]._y << ")" << endl;
i = res[i]._prev;
}*/
//Print(res, i);
stack<_path> st;
DFS(map, 7, 8, st, 0, 0);
while (!st.empty())
{
cout << "(" << st.top()._x << "," << st.top()._y << ")" << endl;
st.pop();
}
}
🚀运行结果

可以返现这个路径仍然是从终点到起点的,所以如果想要正序输出那么仍然要做修正。
但是还要注意的是,迷宫中有两条路径,栈中只记录了一条路径,恰巧这个路径是最短路径,注意这是恰巧,这和你第一步的走向有关。如果你改变走向结果也可能会变,所以DFS并不适合求最短路径,但是用来求路径还是没毛病的。
bool DFS(int map[][8], int row, int col, stack<_path>& st,int i,int j)
{
st.push(_path(i, j));
map[i][j] = -1;
if (i == row - 1 && j == col - 1)
return true;
if (check(i, j + 1, map, row, col)) //先向右走
if (DFS(map, row, col, st, i, j + 1))
return true;
if (check(i + 1, j, map, row, col))
if (DFS(map, row, col, st, i + 1, j))
return true;
if (check(i - 1, j, map, row, col))
if (DFS(map, row, col, st, i - 1, j))
return true;
if (check(i, j - 1, map, row, col))
if (DFS(map, row, col, st, i, j - 1))
return true;
map[i][j] = 0;
st.pop();
return false;
}

🚀可以看到先向右走的时候,栈中存储的数据就是另一条路径了,这也验证了DFS不适合求最短路径。注意我说的是不适合不代表DFS不能求最短路径。
🚀思路
求所有路径,我们可以使用vector,每一步都记录在vector中,如果当前位置到达了终点,那么就打印vector中的路径。
🚀代码
void DFS2(int map[][8], int row, int col, int i, int j, vector<_path> v)
{
v.push_back(_path(i, j));
map[i][j] = -1;
if (i == row - 1 && j == col - 1)
{
for (int i = 0; i < v.size(); i++)
{
cout << "(" << v[i]._x << "," << v[i]._y << ")" << endl;
}
cout << "-------------------------------" << endl;
}
if (check(i, j + 1, map, row, col)) //先向右走
DFS2(map, row, col, i, j + 1,v);
if (check(i + 1, j, map, row, col))
DFS2(map, row, col, i + 1, j, v);
if (check(i - 1, j, map, row, col))
DFS2(map, row, col, i - 1, j,v);
if (check(i, j - 1, map, row, col))
DFS2(map, row, col, i, j - 1,v);
map[i][j] = 0;
}
🚀结果展示

我想为Heroku构建一个Rails3应用程序。他们使用Postgres作为他们的数据库,所以我通过MacPorts安装了postgres9.0。现在我需要一个postgresgem并且共识是出于性能原因你想要pggem。但是我对我得到的错误感到非常困惑当我尝试在rvm下通过geminstall安装pg时。我已经非常明确地指定了所有postgres目录的位置可以找到但仍然无法完成安装:$envARCHFLAGS='-archx86_64'geminstallpg--\--with-pg-config=/opt/local/var/db/postgresql90/defaultdb/po
尝试通过RVM将RubyGems升级到版本1.8.10并出现此错误:$rvmrubygemslatestRemovingoldRubygemsfiles...Installingrubygems-1.8.10forruby-1.9.2-p180...ERROR:Errorrunning'GEM_PATH="/Users/foo/.rvm/gems/ruby-1.9.2-p180:/Users/foo/.rvm/gems/ruby-1.9.2-p180@global:/Users/foo/.rvm/gems/ruby-1.9.2-p180:/Users/foo/.rvm/gems/rub
我的最终目标是安装当前版本的RubyonRails。我在OSXMountainLion上运行。到目前为止,这是我的过程:已安装的RVM$\curl-Lhttps://get.rvm.io|bash-sstable检查已知(我假设已批准)安装$rvmlistknown我看到当前的稳定版本可用[ruby-]2.0.0[-p247]输入命令安装$rvminstall2.0.0-p247注意:我也试过这些安装命令$rvminstallruby-2.0.0-p247$rvminstallruby=2.0.0-p247我很快就无处可去了。结果:$rvminstall2.0.0-p247Search
由于fast-stemmer的问题,我很难安装我想要的任何rubygem。我把我得到的错误放在下面。Buildingnativeextensions.Thiscouldtakeawhile...ERROR:Errorinstallingfast-stemmer:ERROR:Failedtobuildgemnativeextension./System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/bin/rubyextconf.rbcreatingMakefilemake"DESTDIR="cleanmake"DESTDIR=
当我尝试安装Ruby时遇到此错误。我试过查看this和this但无济于事➜~brewinstallrubyWarning:YouareusingOSX10.12.Wedonotprovidesupportforthispre-releaseversion.Youmayencounterbuildfailuresorotherbreakages.Pleasecreatepull-requestsinsteadoffilingissues.==>Installingdependenciesforruby:readline,libyaml,makedepend==>Installingrub
我正在尝试使用boilerpipe来自JRuby。我看过guide从JRuby调用Java,并成功地将它与另一个Java包一起使用,但无法弄清楚为什么同样的东西不能用于boilerpipe。我正在尝试基本上从JRuby中执行与此Java等效的操作:URLurl=newURL("http://www.example.com/some-location/index.html");Stringtext=ArticleExtractor.INSTANCE.getText(url);在JRuby中试过这个:require'java'url=java.net.URL.new("http://www
我意识到这可能是一个非常基本的问题,但我现在已经花了几天时间回过头来解决这个问题,但出于某种原因,Google就是没有帮助我。(我认为部分问题在于我是一个初学者,我不知道该问什么......)我也看过O'Reilly的RubyCookbook和RailsAPI,但我仍然停留在这个问题上.我找到了一些关于多态关系的信息,但它似乎不是我需要的(尽管如果我错了请告诉我)。我正在尝试调整MichaelHartl'stutorial创建一个包含用户、文章和评论的博客应用程序(不使用脚手架)。我希望评论既属于用户又属于文章。我的主要问题是:我不知道如何将当前文章的ID放入评论Controller。
首先回顾一下拉格朗日定理的内容:函数f(x)是在闭区间[a,b]上连续、开区间(a,b)上可导的函数,那么至少存在一个,使得:通过这个表达式我们可以知道,f(x)是函数的主体,a和b可以看作是主体函数f(x)中所取的两个值。那么可以有, 也就意味着我们可以用来替换 这种替换可以用在求某些多项式差的极限中。方法: 外层函数f(x)是一致的,并且h(x)和g(x)是等价无穷小。此时,利用拉格朗日定理,将原式替换为 ,再进行求解,往往会省去复合函数求极限的很多麻烦。使用要注意:1.要先找到主体函数f(x),即外层函数必须相同。2.f(x)找到后,复合部分是等价无穷小。3.要满足作差的形式。如果是加
SPI接收数据左移一位问题目录SPI接收数据左移一位问题一、问题描述二、问题分析三、探究原理四、经验总结最近在工作在学习调试SPI的过程中遇到一个问题——接收数据整体向左移了一位(1bit)。SPI数据收发是数据交换,因此接收数据时从第二个字节开始才是有效数据,也就是数据整体向右移一个字节(1byte)。请教前辈之后也没有得到解决,通过在网上查阅前人经验终于解决问题,所以写一个避坑经验总结。实际背景:MCU与一款芯片使用spi通信,MCU作为主机,芯片作为从机。这款芯片采用的是它规定的六线SPI,多了两根线:RDY和INT,这样从机就可以主动请求主机给主机发送数据了。一、问题描述根据从机芯片手
文章目录git常用命令(简介,详细参数往下看)Git提交代码步骤gitpullgitstatusgitaddgitcommitgitpushgit代码冲突合并问题方法一:放弃本地代码方法二:合并代码常用命令以及详细参数gitadd将文件添加到仓库:gitdiff比较文件异同gitlog查看历史记录gitreset代码回滚版本库相关操作远程仓库相关操作分支相关操作创建分支查看分支:gitbranch合并分支:gitmerge删除分支:gitbranch-ddev查看分支合并图:gitlog–graph–pretty=oneline–abbrev-commit撤消某次提交git用户名密码相关配置g