问题描述
给定一个只包含 ‘(’ 和 ‘)’ 的字符串,找出最长的包含有效括号的子串的长度。
输入
输入只有一个包含有’('和’)'字符串。
输出
最长的包含有效括号的子串的长度,没有换行。
样例输入1
(()
样例输出1
2
解释: 最长有效括号子串为 “()”
样例输入2
)()())
样例输出2
4
解释: 最长有效括号子串为 “()()”
思路:解此题的方法基于用栈实现的括号匹配算法。即左括号进栈,右括号与栈顶的左括号匹配,栈顶出栈,最后判断栈是否为空。这题我的想法是构造一个结构体list,有block(表示括号)、hasmatch(是否有匹配)两个元素,首先输入要判断的字符串,给每个list元素赋值。如果list.block为左括号就入栈,如果为右括号,先判断栈是否为空,为空不操作,否则把当前list和栈顶list的hasmatch置为true。最后判断连续hasmatch为true的最大数量即最长子串长度。
注:这里stack里元素的类型是list*,否则无法改变原数组中list的值。
代码
#include<iostream>
#include<stack>
#include<string>
#include<vector>
using namespace std;
struct list {
char block;
bool has_match = false;
};
int main()
{
stack<list*>s;
string blocks;
cin >> blocks;
vector<list> arr; //字符串
list*l = new list[blocks.size()];
for (int i = 0; i < blocks.size(); i++) //赋值
{
l[i].block = blocks[i];
arr.push_back(l[i]);
}
for (int i = 0; i < blocks.size(); i++) //栈操作
{
if (arr[i].block == '(') //左括号进栈
s.push(&arr[i]);
else
{
if (!s.empty()) //判断是否为空
{
if ((*s.top()).has_match == false) //emmmmm这个判断其实没必要
{
arr[i].has_match = true;
(*s.top()).has_match = true; //把左右括号hasmatch改为true
s.pop();
}
}
}
}
int num = 0;
int max = 0;
for (int i = 0; i < arr.size(); i++) //找最长子串
{
if (arr[i].has_match == true)
num++;
else
{
if (num > max)
max = num;
num = 0;
}
}
if (num > max)
max = num;
cout << max;
return 0;
}