任务要求:输入一个由括号'(
',')
','{
','}
','[
',']
'组成的字符串,判断字符串是否合法,写程序完成此转换,要求使用class类。部分代码已给出,请将代码填补完整。合法是指括号按顺序结束,如‘()’
和‘([])’
是有效的,而’{]’
和’([)]’
不是合法的。
思路:挨个判断每一个括号是否能在整个数组中找到配对的括号,同时判断其相邻处是否有其他类型的且方向相同的括号,从而排除括号被截断的情况。括号的顺序和位置都重要。
#include <iostream>
#include <string>
using namespace std;
class Solution {
public:
bool isValid(string s) {
bool res = 0;
int i = 0;
while( i<s.length() ){
if (s[i] == '(') {
int j = i + 1;
while ((s[j] != ')' && j < s.length())) {
j++;
}
if (s[j] == ')' && s[i + 1] != ']' && s[i + 1] != '}') { i++; }
else break;
}
else if (s[i] == '[') {
int j = i + 1;
while ((s[j] != ']' && j < s.length())) {
j++;
}
if (s[j] == ']' && s[i + 1] != ')' && s[i + 1] != '}') { i++; }
else break;
}
else if (s[i] == '{') {
int j = i + 1;
while ((s[j] != '}' && j < s.length())) {
j++;
}
if (s[j] == '}' && s[i + 1] != ')' && s[i + 1] != ']') { i++; }
else break;
}//如果找完了所有的左括号了都没问题,我们到了右括号的位置:
else {
if (s[i] == ')') {
int j = i - 1;
while (s[j] != '(' && j > 0) {
j--;
}
if ((s[j] == '(') && s[i - 1] != '[' && s[i - 1] != '{') { i++; }
else break;
}
else if (s[i] == ']') {
int j = i - 1;
while (s[j] != '[' && j > 0) {
j--;
}
if ((s[j] == '[') && s[i - 1] != '(' && s[i - 1] != '{') { i++; }
else break;
}
else if (s[i] == '}') {
int j = i - 1;
while (s[j] != '{' && j > 0) {//这里有个问题是最后整了一个s[-1]。。。
j--;
}
if ((s[j] == '{') && s[i - 1] != '[' && s[i - 1] != '(') { i++; }
else break;
}
}
}
if (i == s.length()) res = 1;//为什么不是i+1:因为最后一个字符如果通过的话i还会加一,所以这里不用加1
return res;
}
};
int main() {
Solution s;
string str;
getline(cin, str);
bool res = s.isValid(str);
cout << res;
return 0;
}
个人认为较好的几个测试例:
- ()[]}:一个右括号找不到配对左括号的情况。
- 可能存在的问题是,在挨个查找右括号的配对括号的时候使用了自减(j--),自减如果成了负数,在字符数组中可能引发报错。
- 解决方法:循环终止条件写为j<0而非j<=0,然后在循环外判断j=0的边界情况
- ([]){}:合法情形
- ([)]:括号被截断的情形