简答题最后一题,编程实现所有括号的合法匹配
如输入3
输出:"((()))”, “(()())”, “(())()”, “()(())”, “()()()”
思路:深搜DFS,关键在于记录已经用掉的左括号个数和右括号的个数,当用过的左括号个数小于右括号则非法;当二者个数和大于2N则非法;当二者个数相等且数目等于2N此时输出。
[cpp] view plaincopyprint?
- #include <iostream>
- using namespace std;
- void DFS_bracket(char* str,int n, int left_used, int right_used)
- {
- if(left_used == right_used && left_used + right_used == 2*n)
- {
- for(int i = 0; i < left_used*2; ++i)
- cout<<str[i];
- 10. cout<<endl;
- 11. return;
- 12. }
- 13. if(left_used < right_used || left_used + right_used >= 2*n)
- 14. {
- 15. return ;
- 16. }
- 17. int index = left_used + right_used;
- 18. str[index] = '(';
- 19. DFS_bracket(str, n, left_used + 1, right_used);
- 20.
- 21. str[index] = ')';
- 22. DFS_bracket(str, n, left_used, right_used + 1);
23. }
24. int main()
25. {
- 26. int parenthesisnum;
- 27. cin>>parenthesisnum;
- 28.
- 29. char* str = new char[parenthesisnum*2+1];
- 30. DFS_bracket(str,parenthesisnum,0,0);
- system(“pause”);
- 31. return 0;
32. }
据说这是一道某公司的面试题,我们先来分析一下。括号匹配有合法有的不合法 如 (()))( 这样就不是合法的匹配样式。为了避免这种情况的出现,记录当前左括号的个数和右括号的个数,使右括号的个数不大于左括号的个数。主要思想类似于0-1背包问题,当进行到某一步的时候 有两种方法:放'(' 和 放 ')'
[cpp] view plaincopyprint?
- void maching(int left,int right,int sum,vector<char> bracket)
- {
- if (left==sum&&right==sum) //如果左边和右边都为要匹配的个数,则输出结果
- {
- vector<char>::iterator iter=bracket.begin();
- for ( ;iter!=bracket.end();iter++)
- {
- cout<<*iter<<' ';
- }
- 10. cout<<endl;
- 11. return ;
- 12. }
- 13. if (left<=sum)
- 14. {
- 15. bracket.push_back('('); //放入左括号,然后递归
- 16. maching(left+1,right,sum,bracket);
- 17. bracket.pop_back(); //递归后弹出左括号
- 18. }
- 19.
- 20. if (left>right&&left<=sum)
- 21. {
- 22. bracket.push_back(')');
- 23. maching(left,right+1,sum,bracket);
- 24. bracket.pop_back();
- 25. }
26. }
27. int main(int argc, char* argv[])
28. {
- 29. vector<char> bracket; //记录当前的匹配样式
- 30. int num;
- 31. cin>>num; //输入括号的个数
- 32. maching(0,0,num,bracket);
- 33. return 0;
34. }