首页 > 编程语言 >22.回溯算法

22.回溯算法

时间:2023-06-25 13:45:04浏览次数:29  
标签:const matrix 22 cols char 算法 str 回溯 row

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

相关文章

  • 222
    ##Restormer:EfficientTransformerforHigh-ResolutionImageRestoration##SyedWaqasZamir,AdityaArora,SalmanKhan,MunawarHayat,FahadShahbazKhan,andMing-HsuanYang##https://arxiv.org/abs/2111.09881importtorch#print(torch.__version__)......
  • 机器学习十大算法---1.线性回归
    1.线性回归的模型函数和损失函数线性回归遇到的问题一般是这样的。我们有m个样本,每个样本对应于n维特征和一个结果输出,如下:我们的问题是,对于一个新的,他所对应的是多少呢?如果这个问题里面的y是连续的,则是一个回归问题,否则是一个分类问题。对于n维特征的样......
  • macOS 配置算法(第四版)的开发环境
    Java环境配置前往Adoptium下载他们预编译的JDK17(最新的LTS版本)的安装器,安装好之后,命令行执行java-version,输出如下:openjdkversion"17.0.7"2023-04-18OpenJDKRuntimeEnvironmentTemurin-17.0.7+7(build17.0.7+7)OpenJDK64-BitServerVMTemurin-17.0.7+7(b......
  • 语音信号的哈夫曼编码压缩解压缩算法matlab仿真,输出编码后数据大小,编码树等指标
    1.算法仿真效果matlab2022a仿真结果如下:     2.算法涉及理论知识概要        利用哈夫曼编码进行信息通信可以较大提高信道利用率,缩短信息传输时间,降低传输成本。但是,这要求在发送端通过一个编码系统对待传数据预先编码;在接收端将传来的数据进行译码......
  • 百度网盘下载慢怎么解决2022(4种免费提速方法)
    摘自:http://baike.jld5.cn/news/49696.html工信部终于针对网盘免费用户下载速度慢的问题出手了,要求各网盘企业在同样的网络条件下,对免费用户提供的上传和下载的最低速率应确保满足基本的下载需求,并且要求此项任务于2021年12月底前完成。看到这则消息时,给小编的第一感觉是网盘免......
  • m基于多属性决策判决算法的异构网络垂直切换matlab仿真,异构网络为GSM,TDS,LTE
    1.算法仿真效果matlab2022a仿真结果如下:    2.算法涉及理论知识概要       异构网络垂直切换是指在不同的移动通信网络之间进行快速自适应切换的技术。在异构网络中,不同类型的网络可能具有不同的带宽、延迟、信号强度等性能指标,因此在不同的应用场景下,需要采......
  • 算法练习-day14
    二叉树110.平衡二叉树题意:给定一个二叉树,判断它是否是高度平衡的二叉树。本题中,一棵高度平衡二叉树定义为:一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过1。示例:    思路:本题我们可以自下而上判断二叉树是否为平衡二叉树,以上图为示例,我们先判断15是不是平衡......
  • 相对靠谱公正的22个测速网站
    相对靠谱公正的22个测速网站(或APP或软件)大全(不断更新中)一、电信宽带网页测速网址:https://10000.gd.cn/#/speed预览:二、测速网网址:测速网-专业测网速,网速测试,宽带提速,游戏测速,直播测速,5G测速,物联网监测-SpeedTest.cn预览:测速网在全世界各地维护了大量测......
  • 安装新版VS2022之后,添加EF实体模型没有生成对于的表格
    1)找到vs2022安装路径中的EF6.Utility.CS.ttinclude.tt文件,需要去掉.tt后缀,然后再做以下修改【部分版本直接是EF6.Utility.CS.ttinclude则直接进入第二步】2)修改EF6的实用程序EF6.Utility.CS.ttinclude文件,它默认的位置在:C:\ProgramFiles\MicrosoftVisualStudio\2022\Profes......
  • 算法设计与分析
    记得在课本上标注...只是t某根据ppt的臆测而已...1.算法复杂度分析五大渐近符号常见渐近函数关系常用求和公式2.递归、分治策略写递归式根据递归式求复杂度:迭代画递归树主定理法:(就是代公式)3.堆、堆排序、二叉搜索树堆操作及复杂度扩展堆4.排序算法ppt无5.......