C++ 用连续字符及其路径查找矩阵中最长路径的长度
给定M*N个字符矩阵,求矩阵中从给定源开始的最长路径的长度 注意:最长路径中的所有字符都应递增和递增 按字母顺序彼此连续。我们是 允许在所有8个方向上搜索下一个字符 我已经正确地找到了序列的长度,但是路径中有一个问题。路径不正确。 这是我的密码C++ 用连续字符及其路径查找矩阵中最长路径的长度,c++,algorithm,c++11,C++,Algorithm,C++11,给定M*N个字符矩阵,求矩阵中从给定源开始的最长路径的长度 注意:最长路径中的所有字符都应递增和递增 按字母顺序彼此连续。我们是 允许在所有8个方向上搜索下一个字符 我已经正确地找到了序列的长度,但是路径中有一个问题。路径不正确。 这是我的密码 #include<iostream> #include<vector> using namespace std; //Below array details all 8 posible directions int row[]
#include<iostream>
#include<vector>
using namespace std;
//Below array details all 8 posible directions
int row[] = { -1,-1,-1, 0, 0, 1, 1, 1 };
int col[] = { 1, 0, -1, 1,-1, -1,0, 1 };
int length(char arr[][5], int x, int y, char previous, vector<pair<int,int> > &path, int k)
{
// x and y must be bounded between 0 to 4
if( x < 0 || x > 4 || y > 4 || y < 0)
return 0;
int l = 0;
int max_length = 0;
for( int i = 0; i < 8; i++)
{
// storing next character in search
char ch = arr[x+row[i]][y+col[i]];
//checking whether ch is the next character in the sequence or not
if(ch == previous + 1)
{
//if k != path.size() then we have taken back in
// the sequence so no need to push back character in the path
if(k == path.size())
{
// Pushing co-ordinates of next valid character
path.push_back(make_pair(x+row[i], y+col[i]));
}
else
path.pop_back();
l = 1 + length(arr, x+row[i], y+ col[i], ch , path, ++k);
max_length = max( l, max_length);
}
}
return max_length;
}
int main()
{
char arr[5][5] = {
{ 'd','e','h','x','b'},
{ 'a','o','g','p','e'},
{ 'd','d','c','f','d'},
{ 'e','b','e','a','s'},
{ 'c','d','y','e','n'}
};
vector<pair<int,int> > path;
//Pusing source address
path.push_back(make_pair(2,2));
int k = 1;
int Len = length(arr, 2, 2 , arr[2][2], path, k);
cout << "Length of the Longest sequence is : " << Len + 1 <<endl;
//printing the path
cout << "Path is : "<<endl;
for( pair<int,int> i : path)
{
cout <<"( " << i.first <<","<<i.second <<" )" ;
}
return 0;
}
实际产量:
最长序列的长度为:6
路径是
2,22,13,03,22,31,20,2
预期产量
最长序列的长度为:6
路径是
2,22,13,22,31,20,2
我的输出中有一个额外的3,0。当我从3,0拿回来的时候,我没能把它打开。
任何帮助都将不胜感激 构建路径的算法不能这样工作。在回溯时,您可以预见不破坏路径,但在回溯之后,当搜索再次向另一个方向深化时,路径将成为两条路径的组合:前一条分支不会从中删除 在实际情况中,第一次尝试是从2,1到3,0。在那里,它发现它无法再深入,但这是迄今为止最好的途径。然后返回到2,1。这条路不会缩短,因为它仍然是最好的。然后搜索再次深入到3,2。然后将此地址添加到路径中,这使得路径不一致 它不能那样工作。当你找到一条更好的路径时,你需要创建一条新的路径,并确保它不再被改变。只有当你找到一条更好的道路时,你才能完全取代它 我还建议限制函数的参数++k也是一个问题,但是我们可以不限制它。让函数返回最长路径,而不是改变路径参数。长度始终可以从中导出 下面是修改函数的方法:
#include<iostream>
#include<vector>
using namespace std;
//Below array details all 8 posible directions
int row[] = { -1,-1,-1, 0, 0, 1, 1, 1 };
int col[] = { 1, 0, -1, 1,-1, -1,0, 1 };
vector<pair<int,int> > longestPath(char arr[][5], int x, int y)
{
char previous = arr[x][y];
vector<pair<int,int> > path; // a new(!) path
// x and y must be bounded between 0 to 4
if( x < 0 || x > 4 || y > 4 || y < 0)
return path;
for (int i = 0; i < 8; i++)
{
// storing next character in search
char ch = arr[x+row[i]][y+col[i]];
//checking whether ch is the next character in the sequence or not
if(ch == previous + 1)
{
vector<pair<int,int> > foundPath = longestPath(arr, x+row[i], y+ col[i]);
if (foundPath.size() > path.size())
path = foundPath;
}
}
path.insert(path.begin(), make_pair(x,y));
return path;
}
int main()
{
char arr[5][5] = {
{ 'd','e','h','x','b'},
{ 'a','o','g','p','e'},
{ 'd','d','c','f','d'},
{ 'e','b','e','a','s'},
{ 'c','d','y','e','n'}
};
vector<pair<int,int> > path = longestPath(arr, 2, 2);
//printing the path
cout << "Path is : "<<endl;
for( pair<int,int> i : path)
{
cout <<"( " << i.first <<","<<i.second <<" )" ;
}
return 0;
}
与其从实现开始并向我们展示它,不如从抽象算法和数据结构开始,并确保尽可能做到这一点。此外,我建议不要太过关注单个指令和循环变量的序列,而是关注它的全局 因此,这里有一个相对简单的算法: 为潜在路径中的每个节点运行一个阶段:因此,在您的情况下,最多26个阶段。 在每个阶段,您都会持有路径可以到达的矩阵位置集;然后导出这些路径可以通过另一个步骤到达的位置集。换言之,你一步一步地沿着许多道路前进。 相位动作可以通过尝试从每个前面位置向前移动来实现,例如检查前面的哪个“f”有相邻的“g”;或者尝试从每个矩阵元素向后移动,并为阶段设置适当的值,例如,搜索矩阵中哪个g与前面的f相邻。 这与您的方法不同,因为在单个路径上没有递归。这种递归可能会很快爆发。虽然你的路径长度不能超过26个字符,但这个原则是有问题的。假设有一个对角矩阵,如下所示:
abcde ...
bcde ...
cde ...
de ...
e ...
.
.
.
任何向左和向下移动的组合都是有效路径;因此有2^k条路径,长度为k,从a开始。是否要调用最长路径2^26次?如果你不需要的话,就不会- 3,0来自哪里?您是否尝试过使用调试器逐行检查代码?