进一步通过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

     回溯方法遍历树状数据时。模拟逻辑问题,将抽象问题转换为清晰的图像,从而确定思路的是一种行之有效的方法。

     我的愿望是 博文对你有帮助-有人点赞!

     

 

posted on 2016-06-28 16:09  Elapsed_Time  阅读(1121)  评论(0编辑  收藏  举报