实现所有括号的合法匹配

简答题最后一题,编程实现所有括号的合法匹配

如输入3

输出:"((()))”, “(()())”, “(())()”, “()(())”, “()()()”

思路:深搜DFS,关键在于记录已经用掉的左括号个数和右括号的个数,当用过的左括号个数小于右括号则非法;当二者个数和大于2N则非法;当二者个数相等且数目等于2N此时输出。

[cpp] view plaincopyprint?

  1. #include <iostream>   
  2. using namespace std;  
  3.   
  4. void DFS_bracket(char* str,int n, int left_used, int right_used)  
  5. {  
  6.     if(left_used == right_used && left_used + right_used == 2*n)  
  7.     {  
  8.         for(int i = 0; i < left_used*2; ++i)  
  9.             cout<<str[i];  
  10. 10.         cout<<endl;  
  11. 11.         return;  
  12. 12.     }  
  13. 13.     if(left_used < right_used || left_used + right_used >= 2*n)  
  14. 14.     {  
  15. 15.         return ;  
  16. 16.     }  
  17. 17.     int index = left_used + right_used;  
  18. 18.     str[index] = '(';  
  19. 19.     DFS_bracket(str, n, left_used + 1, right_used);  
  20. 20.    
  21. 21.     str[index] = ')';  
  22. 22.     DFS_bracket(str, n, left_used, right_used + 1);  

23. }  

24. int main()  

25. {  

  1. 26.     int parenthesisnum;  
  2. 27.     cin>>parenthesisnum;  
  3. 28.   
  4. 29.     char* str = new char[parenthesisnum*2+1];  
  5. 30.     DFS_bracket(str,parenthesisnum,0,0);  
    1. system(“pause”);
  6. 31.     return 0;  

32. }  

 

据说这是一道某公司的面试题,我们先来分析一下。括号匹配有合法有的不合法 如 (()))( 这样就不是合法的匹配样式。为了避免这种情况的出现,记录当前左括号的个数和右括号的个数,使右括号的个数不大于左括号的个数。主要思想类似于0-1背包问题,当进行到某一步的时候 有两种方法:放'(' 和 放 ')'

[cpp] view plaincopyprint?

  1. void maching(int left,int right,int sum,vector<char> bracket)  
  2. {  
  3.     if (left==sum&&right==sum)  //如果左边和右边都为要匹配的个数,则输出结果   
  4.     {  
  5.         vector<char>::iterator iter=bracket.begin();  
  6.         for ( ;iter!=bracket.end();iter++)    
  7.         {  
  8.             cout<<*iter<<' ';  
  9.         }  
  10. 10.         cout<<endl;  
  11. 11.         return ;  
  12. 12.     }  
  13. 13.     if (left<=sum)  
  14. 14.     {  
  15. 15.         bracket.push_back('(');    //放入左括号,然后递归   
  16. 16.         maching(left+1,right,sum,bracket);  
  17. 17.         bracket.pop_back();        //递归后弹出左括号   
  18. 18.     }  
  19. 19.       
  20. 20.     if (left>right&&left<=sum)  
  21. 21.     {  
  22. 22.         bracket.push_back(')');  
  23. 23.         maching(left,right+1,sum,bracket);  
  24. 24.         bracket.pop_back();  
  25. 25.     }  

26. }  

27. int main(int argc, char* argv[])  

28. {  

  1. 29.     vector<char> bracket;    //记录当前的匹配样式   
  2. 30.     int num;  
  3. 31.     cin>>num;                //输入括号的个数    
  4. 32.     maching(0,0,num,bracket);  
  5. 33.     return 0;  

34. }  

 

posted @ 2013-06-27 17:13  夜雨阑珊  阅读(811)  评论(0编辑  收藏  举报