回溯的基本原理
在问题的解空间中,按深度优先遍历策略,从根节点出发搜索解空间树。算法搜索至解空间
的任意一个节点时,先判断该节点是否包含问题的解。如果确定不包含,跳过对以该节点为根的
子树的搜索,逐层向其祖先节点回溯,否则进入该子树,继续深度优先搜索。
回溯法解问题的所有解时,必须回溯到根节点,且根节点的所有子树都被搜索后才结束。回
溯法解问题的一个解时,只要搜索到问题的一个解就可结束。
回溯的基本步骤
- 定义问题的解空间
- 确定易于搜索的解空间结构
- 以深度优先搜索的策略搜索解空间,并在搜索过程中尽可能避免无效搜索
请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。路径可以
从矩阵中任意一格开始,每一步可以在矩阵中向左、右、上、下移动一格。如果一条路径经过了
矩阵的某一格,那么该路径不能再次进入该格子。例如在下面的 3×4 的矩阵中包含一条字符串
“bfce”的路径(路径中的字母用下划线标出)。但矩阵中不包含字符串“abfb”的路径,因为
字符串的第一个字符 b 占据了矩阵中的第一行第二个格子之后,路径不能再次进入这个格子。
A B T G
C F C S
J D E H
#include<stdio.h>
#include<Windows.h>
//四个参数 传入的字符数组,行,列,搜索的字符串
bool FindChars(const char *marinx,int rows,int cols,const char *str);
//递归的搜索函数 8个参数 传入的字符数组,行,列,搜索到的行,列,搜索字符串,走了多少步,该点是否已经访问
bool hasPath(const char *marinx,int rows,int cols,int row,int col,const char *str,int &Path,bool *visit);
bool FindChars(const char *marinx,int rows,int cols,const char *str){
//防御性编程
if(rows<0||cols<0||marinx==nullptr) return false;
//记录走了多少步,也就是用这个步数来判断str是否已经搜索到
int PathStep = 0;
bool *visit = new bool[rows*cols];
memset(visit,0,rows*cols);
for(int row=0;row<rows;row++){
for(int col=0;col<cols;col++){
if(hasPath(marinx,rows,cols,row,col,str,PathStep,visit)) return true;
}
}
delete []visit;
return false;
}
bool hasPath(const char *marinx,int rows,int cols,int row,int col,const char *str,int &Path,bool *visit){
//搜索成果条件,到了str的字符串结束符
if(str[Path]=='\0') return true;
//进入的条件,首先这个点要在这个数组内,其次这个点没被访问过并且这个点等于这个str[Path]
bool haspath = false;//一个标志位记录有没有路
if(row<rows&&row>=0&&col>=0&&col<cols&&marinx[row*cols+col]==str[Path]&&visit[row*cols+col]==false){
//不行的情况
//此时这个点是没有访问的并且满足条件
Path++;
visit[row*cols+col] = true;
//进入下一个点
haspath = hasPath(marinx,rows,cols,row+1,col,str,Path,visit)
||hasPath(marinx,rows,cols,row-1,col,str,Path,visit)
||hasPath(marinx,rows,cols,row,col+1,str,Path,visit)
||hasPath(marinx,rows,cols,row,col-1,str,Path,visit);
//这种是
//当结束深度查找的时候要回溯置位
if(!haspath){
Path--;
visit[row*cols+col] = false;
}
}
return haspath;
}
//测试代码
void test(const char *marinx,int rows,int cols,const char *str,bool &isPass){
isPass =FindChars( marinx, rows, cols, str);
if(isPass)printf("Successfully find:%s\n",str);
else printf("hava no find:%s",str);
}
int main(void){
char marinx[]={ 'A','B','T','G'
,'C','F','C','S',
'J','D','E','B'};
//char *marinx ="ABTGCFCSJDEB";
char *str ="ACJDE";
bool ret =false;
test(marinx,3,4,str,ret);
str ="ABTGSBEDJCFC";
test(marinx,3,4,str,ret);
system("pause");
return 0;
}