Problem Description
括号匹配,输入测试数目n,接着n行输入n组样例,假设只包含小括号和中括号。
Input
首先输入测试数目n,接着n行输入n组样例,假设只包含小括号和中括号。
Output
若括号可以成对匹配,则输出 yes ,否则输出 no 。
Sample Input
4
()()()(())
([])[)
([)]
]
Sample Output
yes
no
yes
no
解题思路
- 定义两个int类型变量small和mid记录小括号和中括号的左括号个数,初值为0。
- 定义一个bool类型变量isMatch表示是否匹配成功,初值为true。
- 遍历输入的括号字符串:
- 遇到左括号变量加1;
- 遇到右括号看左括号的个数,若个数为0,则匹配失败,isMatch置为false;若个数不为0,则匹配成功,左括号变量数减1。
- 遍历为括号字符串,当左括号数都为0且isMatch为true时,所有括号成对匹配。
经验总结
- 也可以用C语言实现栈的数据结构。
- 遇到左括号进栈;遇到右括号→判空→匹配成功出栈。
- 遍历结束后,栈空且匹配成功标志为true,则所有括号成对匹配。
代码实现(C)
- 变量实现:
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
#define MaxSize 10000
int main() {
int n;
char str[MaxSize];
while (~scanf("%d", &n)) {
for (int i = 0; i < n; ++i) {
int small = 0, mid = 0; // small表示右括号数,mid表示左括号数
bool isMatch = true; // 表示是否匹配成功
scanf("%s", str); // 录入数据
// 遍历括号字符串
for (int j = 0; j < strlen(str); ++j) {
switch (str[j]) {
case '(': // 遇到左括号
small++; // 累加
break;
case ')': // 右括号
if (small == 0) // 左括号数为0
isMatch = false; // 匹配失败
else
small--; // 匹配成功,左括号数减少
break;
case '[':
mid++;
break;
case ']':
if (mid == 0)
isMatch = false;
else
mid--;
break;
}
}
// 遍历结束时,左括号为0且无匹配失败情况,则所有括号成对匹配
if (small == 0 && mid == 0 && isMatch)
printf("yes\n");
else
printf("no\n");
}
}
return 0;
}
- 栈实现
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
#define MaxSize 10000
typedef char ElemType;
typedef struct Stack {
ElemType data[MaxSize]; // 数组实现栈
int top; // 栈顶指针
} Stack;
// 初始化
void init(Stack *s) {
s->top = -1; // 初始时栈顶指针为-1;
}
// 判空
bool empty(Stack s) {
return s.top == -1;
}
// 进栈
bool push(Stack *s, ElemType e) {
if (s->top == MaxSize - 1) // 判满
return false;
s->data[++s->top] = e; // 栈顶指针后移->进栈
return true;
}
// 出栈
bool pop(Stack *s) {
if (empty(*s)) // 判空
return false;
s->top--; // 栈顶指针前移
return true;
}
int main() {
int n;
char str[MaxSize];
while (~scanf("%d", &n)) {
for (int i = 0; i < n; ++i) {
Stack small, mid; // 创建栈
init(&small); // 初始化
init(&mid);
bool isMatch = true; // 表示是否匹配成功
scanf("%s", str); // 录入数据
for (int j = 0; j < strlen(str); ++j) {
switch (str[j]) {
case '(': // 遇到左括号
push(&small, str[j]); // 入栈
break;
case ')': // 遇到右括号
if (empty(small)) // 栈空,左括号数为0
isMatch = false; // 匹配失败
else
pop(&small); // 匹配成功,出栈
break;
case '[':
push(&mid, str[j]);
break;
case ']':
if (empty(mid))
isMatch = false;
else
pop(&mid);
break;
}
}
if (empty(small) && empty(mid) && isMatch)
printf("yes\n");
else
printf("no\n");
}
}
return 0;
}