/*
ACM的括号匹配(二)
*/
#include <iostream>
#include <string>
using namespace std;
//判断传入的两个字符是否匹配
bool Matched(char a, char b)
{
if((a == '(' && b == ')') || (a == '[' && b == ']'))
return true;
return false;
}
int main()
{
const int ARRCUT = 100; //二维数组的大小
//beg:表示开始的字符 end表示结束的字符 index好似一个寻找匹配符号的索引器(或游标) arr:一个二维数组
int N, i, beg, end, index, arr[ARRCUT][ARRCUT];
string S;
cin >> N;
while(N--)
{
cin >> S;
//因为不存在空串,所以如果该字符串只有1个字符,可直接输出需要匹配的括号数量为1
if(S.size() == 1)
{
cout << 1 << endl;
continue;
}
//memset方法不给用(用了会报错,郁闷,所以自己动手吧)将数组的数据全部赋为0
for(beg = 0; beg < ARRCUT; ++beg)
for(end = 0; end < ARRCUT; ++end)
arr[beg][end] = 0;
//表示自己到自己的匹配数为1
for(i = 0; i < ARRCUT; ++i)
arr[i][i] = 1;
//下面开始真正的匹配工作了,把end指到第二个字符
for(end = 1; end < S.size(); ++end)
{
//把beg指到end的前面一个字符
for(beg = end - 1; beg >= 0; --beg)
{
//先求出从beg到end之间的匹配数(简称匹配数)吧,就是在(从beg到end减一的距离)之上加1
arr[beg][end] = arr[beg][end - 1] + 1;
//把游标指向beg的位置,开始向后不断地寻找和end相匹配的符号
for(index = beg; index < end; ++index)
{
//如果找到了匹配的符号
if(Matched(S[index], S[end]))
{
//如果游标的位置等于beg的位置,说明游标还没有移动过
if(index == beg)
//就把匹配数改写成从游标的下一位置开始到end前面一个字符之间的数字吧
arr[beg][end] = arr[index + 1][end - 1];
else
//否则,就是游标移动了,那么匹配数就得再加上beg位置到游标之前位置的数量了
arr[beg][end] = min(arr[beg][end], arr[beg][index - 1] + arr[index + 1][end -1]);
}
}
}
}
//输出也写一下吧,输出从第一个字符开始直到最后一个字符之间需要匹配的符号数:)
cout << arr[0][S.size() - 1] << endl;
}
return 0;
}
</string></iostream>