有效的括号
给定一个只包括 '('
,')'
,'{'
,'}'
,'['
,']'
的字符串 s
,判断字符串是否有效。
有效字符串需满足:
- 左括号必须用相同类型的右括号闭合。
- 左括号必须以正确的顺序闭合。
- 每个右括号都有一个对应的相同类型的左括号。
1.化简思维
可以将问题先简化为1种括号的匹配问题(判断左括号、右括号的数量是否相等),再扩展括号匹配的种类:
+1
可以等价为进入,-1
可以等价为出去
- 一对
()
可以等价为一个完整的事件
(())
可以看做事件与事件之间的完全包含关系
1种括号匹配
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| bool isValid(char *s) { int lum = 0, rnum = 0; int len = strlen(s); for (int i = 0; i < len; ++i) { switch (s[i]) { case '(' : ++lnum; break; case ')' : ++rnum; break; default : return flase; } if (lnum >= rnum) continue; return false; } return lnum = rnum; }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| bool isValid(char *s) { int lum = 0; int len = strlen(s); for (int i = 0; i < len; ++i) { switch (s[i]) { case '(' : ++lnum; break; case ')' : --rnum; break; default : return flase; } if (lnum >= 0) continue; return false; } return lnum = 0; }
|
多种括号匹配
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
| #include<iostream> #include<stdio.h> #include<string.h> using namespace std;
bool judgeOne(char *s, int *i, int d) { bool flag = true; int j = d; while (s[*i] && flag) { switch (s[*i]) { case '(' : ++(*i); flag = judgeOne(s, i, d + 1); if (s[*i] == ')') {++(*i); flag &= true;} else if (s[*i] == ']' || s[*i] == '}' || s[*i] == '\0') flag = false; break; case '[' : ++(*i); flag = judgeOne(s, i, d + 1); if (s[*i] == ']') {++(*i); flag &= true;} else if (s[*i] == ')' || s[*i] == '}' || s[*i] == '\0') flag = false; break; case '{' : ++(*i); flag = judgeOne(s, i, d + 1); if (s[*i] == '}') {++(*i); flag &= true;} else if (s[*i] == ')' || s[*i] == ']' || s[*i] == '\0') flag = false; break; case ')' : case ']' : case '}' : return j = 0 ? false : true && flag; default : return false; } } return flag; }
bool isValid(char * s) { int i = 0, len = strlen(s); bool flag = true; while (i < len && flag) { flag &= judgeOne(s, &i, 0); } return flag; }
int main() { char s[1000]; cin >> s; cout << s << " isValid : " << isValid(s) << endl; return 0; }
|
注意:该程序虽然可以判断成功,但是执行的时间复杂度太高导致超时。
2.Stack
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
| #include <iostream> using namespace std;
typedef struct Stack { char *base; int top; int stackSize; } Stack;
void InitStack(Stack &s, int n) { s.base = new char[100000]; s.stackSize = n; s.top = -1; };
bool EmptyStack(Stack &s) { return s.top == -1; }
void PushStack(Stack &s, char c) { s.top++; s.base[s.top] = c; }
void PopStack(Stack &s) { s.top--; }
char GetTop(Stack &s) { return s.base[s.top]; }
bool isValid(string s) { int len = s.length(); Stack stack; InitStack(stack, len); for (int i = 0; i < len; ++i) { switch (s[i]) { case '(': case '[': case '{': PushStack(stack, s[i]); break; case ')': if (EmptyStack(stack)) return false; if (GetTop(stack) != '(') return false; PopStack(stack); break; case '}': if (EmptyStack(stack)) return false; if (GetTop(stack) != '{') return false; PopStack(stack); break; case ']': if (EmptyStack(stack)) return false; if (GetTop(stack) != '[') return false; PopStack(stack); break; } } return EmptyStack(stack); }
int main() { char s[1000]; cin >> s; cout << s << "isValid : " << isValid(s) << endl; return 0; }
|