进一步通过OJ题学习DFS。掌握递归回溯思想。
ZOJ1004,用进栈出栈的操作将字符串转换为目标字符串。输出io方式。
解题思路:
在了解此题是回溯算法的应用后。在草稿上画出了获取目标字符串的所有IO方式。当栈中有元素且源字符串的迭代没有到达末尾时,对栈的操作有两种方式。
一种是继续将字符串元素压入栈中,令一种则是弹出栈顶元素与目标字符串匹配,检测是否成功匹配。
模拟进栈出栈的操作后,可以得到一个树状图。右分支为出栈操作,当栈中无元素时递归或者栈顶元素与目标字符不匹配时递归终止,回溯。左分支为进栈操作,当源字符串没有全部压入栈中时,递归,否则,回溯。
1 #include <iostream> 2 #include <stack> 3 #include <string> 4 #include <vector> 5 #define MAX 1000 6 using namespace std; 7 8 vector<char> resultVec; 9 stack<char> cSta; 10 11 void dfs(const string& src,const string& dst,int srcPos = 0,int dstPos = 0) 12 { 13 14 if ( cSta.empty() && dstPos == dst.size() ){ //成功完全匹配 15 for ( auto i : resultVec ) 16 cout << i <<" "; 17 cout << endl; 18 return ; 19 } 20 21 if ( srcPos != src.size() ){ //判断源字符串是否完全入栈 22 cSta.push(src[srcPos]); 23 resultVec.push_back('i'); 24 dfs(src,dst,srcPos+1,dstPos); //进入下一层递归函数,执行到检测判断top是否与目标字符串相同 25 cSta.pop(); //若不匹配,递归回溯,取消之前的进栈操作(出栈) 26 resultVec.pop_back(); 27 } 28 29 if ( !cSta.empty() && dstPos != dst.size() && cSta.top() == dst[dstPos] ){ 30 //if( cSta.top() == dst[dstPos] ) 可将总条件判断移至这里 31 char tmp = cSta.top(); 32 cSta.pop(); //匹配成功,出栈 33 resultVec.push_back('o'); 34 dfs(src,dst,srcPos,dstPos+1); 35 cSta.push(tmp);//深度溯进时遇到不匹配项,则取消pop 重新进栈 36 resultVec.pop_back(); 37 } 38 } 39 40 int main() 41 { 42 string src; //源字符串 43 string dst; //目标字符串 44 45 while ( cin >> src >> dst ){ 46 if ( src.size() != dst.size() ) cout << "[\n]" << endl; 47 else{ 48 cout << "[\n"; 49 dfs(src,dst); 50 cout <<"]\n"; 51 } 52 } 53 return 0; 54 }//Achieve
回溯方法遍历树状数据时。模拟逻辑问题,将抽象问题转换为清晰的图像,从而确定思路的是一种行之有效的方法。
我的愿望是 博文对你有帮助-有人点赞!