1.回溯的基本原理
在问题的解空间中,按深度优先遍历策略,从根节点出发搜索解空间树。算法搜索至解空间的任意一个节点时,先判断该节点是否包含问题的解。如果确定不包含,跳过对以该节点为根的子树的搜索,逐层向其祖先节点回溯,否则进入该子树,继续深度优先搜索。
回溯法解问题的所有解时,必须回溯到根节点,且根节点的所有子树都被搜索后才结束。回溯法解问题的一个解时,只要搜索到问题的一个解就可结束。
2.回溯的基本步骤
1.定义问题的解空间
2.确定易于搜索的解空间结构
3.以深度优先搜索的策略搜索解空间,并在搜索过程中尽可能避免无效搜索
名企面试题:
请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。路径可以从矩阵中任意一格开始,每一步可以在矩阵中向左、右、上、下移动一格。如果一条路径经过了矩阵的某一格,那么该路径不能再次进入该格子。例如在下面的3×4的矩阵中包含一条字符串“bfce”的路径(路径中的字母用下划线标出)。但矩阵中不包含字符串“abfb”的路径,因为字符串的第一个字符b占据了矩阵中的第一行第二个格子之后,路径不能再次进入这个格子。
A B T G
C F C S
J D E H
解题思路:
首先,在矩阵中任选一个格子作为路径的起点。如果路径上的第i 个字符不是待搜索的目标字符ch,那么这个格子不可能处在路径上的第i 个位置。如果路径上的第i 个字符正好是ch,那么往相邻的格子寻找路径上的第i+1 个字符。除在矩阵边界上的格子之外,其他格子都有4个相邻的格子。重复这个过程直到路径上的所有字符都在矩阵中找到相应的位置。由于路径不能重复进入矩阵的格子,还需要定义和字符矩阵大小一样的布尔值矩阵,用来标识路径是否已经进入每个格子。当矩阵中坐标为(row, col)的格子和路径字符串中相应的字符一样时,从4 个相邻的格子(row,col-1),(row-1,col),(row,col+1)以及(row+1,col)中去定位路径字符串中下一个字符, 如果4 个相邻的格子都没有匹配字符串中下一个的字符,表明当前路径字符串中字符在矩阵中的定位不正确,我们需要回到前一个,然后重新定位。
2.1查找矩阵中是否含有str 指定的字串
bool hasPathCore(const char* matrix, int rows, int cols, int row, int col, const char* str, int& pathLength, bool* visited);
/*****************************************
功能: 查找矩阵中是否含有str 指定的字串
参数说明:
matrix 输入矩阵
rows 矩阵行数
cols 矩阵列数
str 要搜索的字符串
返回值: 是否找到true 是,false 否
*******************************************/
bool hasPath(const char* matrix, int rows, int cols, const char* str)
{
if (matrix == nullptr || rows < 1 || cols < 1 || str == nullptr)
return false;
bool* visited = new bool[rows * cols];//用于标记该位置是否已经访问
memset(visited, 0, rows * cols);
int pathLength = 0;
//遍历矩阵中每个点,做为起点开始进行搜索
for (int row = 0; row < rows; ++row)
{
for (int col = 0; col < cols; ++col)
{
if (hasPathCore(matrix, rows, cols, row, col, str, pathLength, visited))
{
return true;
}
}
}
delete[] visited;
return false;
}
2.2探测下一个字符是否存在
/*探测下一个字符是否存在*/
bool hasPathCore(const char* matrix, int rows, int cols, int row, int col, const char* str, int& pathLength, bool* visited)
{
if (str[pathLength] == '\0')
return true;
bool hasPath = false;
if (row >= 0 && row < rows && col >= 0 && col < cols && matrix[row * cols + col] == str[pathLength] && !visited[row * cols + col])
{
++pathLength;
visited[row * cols + col] = true;
hasPath = hasPathCore(matrix, rows, cols, row, col - 1, str, pathLength, visited)
|| hasPathCore(matrix, rows, cols, row - 1, col, str, pathLength, visited)
|| hasPathCore(matrix, rows, cols, row, col + 1, str, pathLength, visited)
|| hasPathCore(matrix, rows, cols, row + 1, col, str, pathLength, visited);
if (!hasPath)
{
--pathLength;
visited[row * cols + col] = false;
}
}
return hasPath;
}
2.3单元测试代码
/*单元测试代码*/
void Test(const char* testName, const char* matrix, int rows, int cols, const char* str, bool expected)
{
if (testName != nullptr)
printf("%s begins: ", testName);
if (hasPath(matrix, rows, cols, str) == expected)
printf("Passed.\n");
else
printf("FAILED.\n");
}
//ABTG
//CFCS
//JDEH
//BFCE
void Test1()
{
const char* matrix = "ABTGCFCSJDEH";
const char* str = "BFCE";
Test("功能测试1", (const char*)matrix, 3, 4, str, true);
}
//ABCE
//SFCS
//ADEE
//SEE
void Test2()
{
const char* matrix = "ABCESFCSADEE";
const char* str = "SEE";
Test("功能测试2", (const char*)matrix, 3, 4, str, true);
}
//ABTG
//CFCS
//JDEH
//ABFB
void Test3()
{
const char* matrix = "ABTGCFCSJDEH";
const char* str = "ABFB";
Test("功能测试3", (const char*)matrix, 3, 4, str, false);
}
//ABCEHJIG
//SFCSLOPQ
//ADEEMNOE
//ADIDEJFM
//VCEIFGGS
//SLHECCEIDEJFGGFIE
void Test4()
{
const char* matrix = "ABCEHJIGSFCSLOPQADEEMNOEADIDEJFMVCEIFGGS";
const char* str = "SLHECCEIDEJFGGFIE";
Test("功能测试4", (const char*)matrix, 5, 8, str, true);
}
//ABCEHJIG
//SFCSLOPQ
//ADEEMNOE
//ADIDEJFM
//VCEIFGGS
//SGGFIECVAASABCEHJIGQEM
void Test5()
{
const char* matrix = "ABCEHJIGSFCSLOPQADEEMNOEADIDEJFMVCEIFGGS";
const char* str = "SGGFIECVAASABCEHJIGQEM";
Test("功能测试5", (const char*)matrix, 5, 8, str, true);
}
//ABCEHJIG
//SFCSLOPQ
//ADEEMNOE
//ADIDEJFM
//VCEIFGGS
//SGGFIECVAASABCEEJIGOEM
void Test6()
{
const char* matrix = "ABCEHJIGSFCSLOPQADEEMNOEADIDEJFMVCEIFGGS";
const char* str = "SGGFIECVAASABCEEJIGOEM";
Test("功能测试6", (const char*)matrix, 5, 8, str, false);
}
//ABCEHJIG
//SFCSLOPQ
//ADEEMNOE
//ADIDEJFM
//VCEIFGGS
//SGGFIECVAASABCEHJIGQEMS
void Test7()
{
const char* matrix = "ABCEHJIGSFCSLOPQADEEMNOEADIDEJFMVCEIFGGS";
const char* str = "SGGFIECVAASABCEHJIGQEMS";
Test("功能测试7", (const char*)matrix, 5, 8, str, false);
}
//AAAA
//AAAA
//AAAA
//AAAAAAAAAAAA
void Test8()
{
const char* matrix = "AAAAAAAAAAAA";
const char* str = "AAAAAAAAAAAA";
Test("边界值测试8", (const char*)matrix, 3, 4, str, true);
}
//AAAA
//AAAA
//AAAA
//AAAAAAAAAAAAA
void Test9()
{
const char* matrix = "AAAAAAAAAAAA";
const char* str = "AAAAAAAAAAAAA";
Test("边界值测试9", (const char*)matrix, 3, 4, str, false);
}
//A
//A
void Test10()
{
const char* matrix = "A";
const char* str = "A";
Test("边界值测试10", (const char*)matrix, 1, 1, str, true);
}
//A
//B
void Test11()
{
const char* matrix = "A";
const char* str = "B";
Test("边界值测试11", (const char*)matrix, 1, 1, str, false);
}
void Test12()
{
Test("特殊情况测试12", nullptr, 0, 0, nullptr, false);
}
完整代码
#include <stdio.h>
#include <string>
using namespace std;
bool hasPathCore(const char* matrix, int rows, int cols, int row, int col, const char* str, int& pathLength, bool* visited);
/*****************************************
功能: 查找矩阵中是否含有str 指定的字串
参数说明:
matrix 输入矩阵
rows 矩阵行数
cols 矩阵列数
str 要搜索的字符串
返回值: 是否找到true 是,false 否
*******************************************/
bool hasPath(const char* matrix, int rows, int cols, const char* str)
{
if (matrix == nullptr || rows < 1 || cols < 1 || str == nullptr)
return false;
bool* visited = new bool[rows * cols];//用于标记该位置是否已经访问
memset(visited, 0, rows * cols);
int pathLength = 0;
//遍历矩阵中每个点,做为起点开始进行搜索
for (int row = 0; row < rows; ++row)
{
for (int col = 0; col < cols; ++col)
{
if (hasPathCore(matrix, rows, cols, row, col, str, pathLength, visited))
{
return true;
}
}
}
delete[] visited;
return false;
}
/*探测下一个字符是否存在*/
bool hasPathCore(const char* matrix, int rows, int cols, int row, int col, const char* str, int& pathLength, bool* visited)
{
if (str[pathLength] == '\0')
return true;
bool hasPath = false;
if (row >= 0 && row < rows && col >= 0 && col < cols && matrix[row * cols + col] == str[pathLength] && !visited[row * cols + col])
{
++pathLength;
visited[row * cols + col] = true;
hasPath = hasPathCore(matrix, rows, cols, row, col - 1, str, pathLength, visited)
|| hasPathCore(matrix, rows, cols, row - 1, col, str, pathLength, visited)
|| hasPathCore(matrix, rows, cols, row, col + 1, str, pathLength, visited)
|| hasPathCore(matrix, rows, cols, row + 1, col, str, pathLength, visited);
if (!hasPath)
{
--pathLength;
visited[row * cols + col] = false;
}
}
return hasPath;
}
/*单元测试代码*/
void Test(const char* testName, const char* matrix, int rows, int cols, const char* str, bool expected)
{
if (testName != nullptr)
printf("%s begins: ", testName);
if (hasPath(matrix, rows, cols, str) == expected)
printf("Passed.\n");
else
printf("FAILED.\n");
}
//ABTG
//CFCS
//JDEH
//BFCE
void Test1()
{
const char* matrix = "ABTGCFCSJDEH";
const char* str = "BFCE";
Test("功能测试1", (const char*)matrix, 3, 4, str, true);
}
//ABCE
//SFCS
//ADEE
//SEE
void Test2()
{
const char* matrix = "ABCESFCSADEE";
const char* str = "SEE";
Test("功能测试2", (const char*)matrix, 3, 4, str, true);
}
//ABTG
//CFCS
//JDEH
//ABFB
void Test3()
{
const char* matrix = "ABTGCFCSJDEH";
const char* str = "ABFB";
Test("功能测试3", (const char*)matrix, 3, 4, str, false);
}
//ABCEHJIG
//SFCSLOPQ
//ADEEMNOE
//ADIDEJFM
//VCEIFGGS
//SLHECCEIDEJFGGFIE
void Test4()
{
const char* matrix = "ABCEHJIGSFCSLOPQADEEMNOEADIDEJFMVCEIFGGS";
const char* str = "SLHECCEIDEJFGGFIE";
Test("功能测试4", (const char*)matrix, 5, 8, str, true);
}
//ABCEHJIG
//SFCSLOPQ
//ADEEMNOE
//ADIDEJFM
//VCEIFGGS
//SGGFIECVAASABCEHJIGQEM
void Test5()
{
const char* matrix = "ABCEHJIGSFCSLOPQADEEMNOEADIDEJFMVCEIFGGS";
const char* str = "SGGFIECVAASABCEHJIGQEM";
Test("功能测试5", (const char*)matrix, 5, 8, str, true);
}
//ABCEHJIG
//SFCSLOPQ
//ADEEMNOE
//ADIDEJFM
//VCEIFGGS
//SGGFIECVAASABCEEJIGOEM
void Test6()
{
const char* matrix = "ABCEHJIGSFCSLOPQADEEMNOEADIDEJFMVCEIFGGS";
const char* str = "SGGFIECVAASABCEEJIGOEM";
Test("功能测试6", (const char*)matrix, 5, 8, str, false);
}
//ABCEHJIG
//SFCSLOPQ
//ADEEMNOE
//ADIDEJFM
//VCEIFGGS
//SGGFIECVAASABCEHJIGQEMS
void Test7()
{
const char* matrix = "ABCEHJIGSFCSLOPQADEEMNOEADIDEJFMVCEIFGGS";
const char* str = "SGGFIECVAASABCEHJIGQEMS";
Test("功能测试7", (const char*)matrix, 5, 8, str, false);
}
//AAAA
//AAAA
//AAAA
//AAAAAAAAAAAA
void Test8()
{
const char* matrix = "AAAAAAAAAAAA";
const char* str = "AAAAAAAAAAAA";
Test("边界值测试8", (const char*)matrix, 3, 4, str, true);
}
//AAAA
//AAAA
//AAAA
//AAAAAAAAAAAAA
void Test9()
{
const char* matrix = "AAAAAAAAAAAA";
const char* str = "AAAAAAAAAAAAA";
Test("边界值测试9", (const char*)matrix, 3, 4, str, false);
}
//A
//A
void Test10()
{
const char* matrix = "A";
const char* str = "A";
Test("边界值测试10", (const char*)matrix, 1, 1, str, true);
}
//A
//B
void Test11()
{
const char* matrix = "A";
const char* str = "B";
Test("边界值测试11", (const char*)matrix, 1, 1, str, false);
}
void Test12()
{
Test("特殊情况测试12", nullptr, 0, 0, nullptr, false);
}
int main(int argc, char* argv[])
{
Test1();
Test2();
Test3();
Test4();
Test5();
Test6();
Test7();
Test8();
Test9();
Test10();
Test11();
Test12();
system("pause");
return 0;
}
参考资料来源:
奇牛学院
标签:const,matrix,22,cols,char,算法,str,回溯,row From: https://www.cnblogs.com/codemagiciant/p/17502713.html