题目描述:

输入格式:
输入一行字符串。
输出格式:
输出一行整数,表示完美括号的最大长度
首先这是经典题目 -- “括号匹配” 的变形。所以,我们能够很快反应到需要使用 “栈” 结构来处理该问题。从更加一般的角度来说,这道题属于 “栈” 结构处理的完全匹配关系。
所以,我们可以很快设计出以下代码段:
- #include
- #include
- #include
- using namespace std;
- const int MAX_LEN = 1e5 + 10;
- char str[MAX_LEN];
- int main() {
- vector<char> stk;
- char ch;
- int res = 0;
- int tmp_res = 0; // 记录临时答案
- scanf("%s", str);
- int len = strlen(str);
- for (int i = 0; i < len; ++i) {
- if (str[i] == '(' || str[i] == '[' || str[i] == '{') stk.push_back(str[i]);
- else {
- if (stk.size() && (str[i] - stk.back() == 2 || str[i] - stk.back() == 1)) stk.pop_back(), tmp_res += 2;
- else {
- stk.push_back('#'); // 压入阻隔信息
- res = max(res, tmp_res);
- tmp_res = 0;
- }
- }
- }
- res = max(res, tmp_res);
- printf("%d", res);
- return 0;
- }
但是,这样的代码段存在BUG。 例如,我们面对测试数据 "((([]{}((()" 时,上述代码会返回 6。而正确答案应该是 4。
这样的BUG来自于上述代码段的“缓式评估”,注意 “栈” 在处理问题时,几乎都运用到了缓式评估的思想。此时,这种思想就成了BUG的来源,因为它会连接本该断开的括号序列。
面对这道难题,我们应该知道当匹配发生时,如果栈不为空,我们不应该直接让 tmp_res += 2。而是单独计算此时的括号序列长度。所以我们需要知道下标信息。但是,下标信息又可以告诉我们字符信息。所以,我们空间就可以减少。
- #include
- #include
- #include
- using namespace std;
- stack<int>stk;
- int i,ans;
- char str[114514],c,cc;
- int main()
- {
- cin>>str;
- int size = strlen(str);
- for(i = 0;i < size; ++i)
- {
- c=str[i];
- if(stk.size())
- {
- cc=str[stk.top()];
- if((c==')'&&cc=='(')||(c==']'&&cc=='[')||(c=='}'&&cc=='{')) stk.pop();
- else stk.push(i); // 压入阻隔信息/压入信息
- } // 尝试匹配
- else stk.push(i); // 压入阻隔信息/压入信息
-
- if(stk.size()) ans=max(ans,i-stk.top()); // 栈有剩余,单独计算长度
- else ans=i+1; // 没有剩余长度就是 i - (-1) == i + 1
- }
- cout<
- return 0;
- }