题目描述
给你一个字符串,里面只有两种字符"(“和”)“。问是否所有”(“都有一个”)"与之匹配。
输入
第一行一个数字T (0<T<=100),表示T组测试数据。
随后T组测试数据,每组测试数据一个字符串str。(0 <= strlen(str) <= 10000)
输出
对于每组测试数据,如果字符串中所有"(“都有一个”)“与之匹配,则输出"yes”, 否则输出"no"
样例输入
2
(())
)(
样例输出
yes
no
思路简介 计数
对字符串进行一位一位的处理
可能出现的情况
1.读取过程中右括号比左括号多 -> no
2.读取过程中左括号一直不比右括号少,但最终左括号比右括号多 -> no
3.读取过程中左括号一直不比右括号少,但最终左括号跟右括号一样多 -> yes
以下两种方法都是基于这样的思路来编写的, 各取所需即可
- AC Code 1
#include <iostream>
#include <string>
using namespace std;
int main ()
{
int T; cin >> T;
while (T--) {
string str; cin >> str;
int len = str.length(); // 获取字符串长度, 进行一位一位判断
int cntLift = 0, cntRight = 0; // 左括号 和 右括号的数量
for (int i = 0; i < len; i++) {
cntLift += str[i] == '('; // 从右向左执行, str[i] == x 成立返回 1(true), 不成立返回 0(false)
cntRight += str[i] == ')';
if (cntRight > cntLift) { // 情况 1
cout << "no\n";
goto no_next; // 直接 return 0没办法进行下一个样例, continue又是对 for执行的,不满足要求, 故选择用 goto
} // 也可用标志变量 + break, 不过我嫌麻烦, 就不用了
}
if (cntLift != cntRight) cout << "no\n"; // 情况 2
else cout << "yes\n"; // 情况 3
no_next:;
}
return 0;
}
- AC Code 2
#include <iostream>
#include <string>
using namespace std;
int main ()
{
int T; cin >> T;
while (T--) {
string str; cin >> str;
int len = str.length(); // 获取字符串长度, 进行一位一位判断
int cntLift = 0; // 左括号的数量
for (int i = 0; i < len; i++) {
if (str[i] == '(') cntLift ++; // 只记录左括号的数量, 如果是右括号, 就让左括号 -1即可
else {
if (cntLift == 0) { // 如果出现右括号 却没有左括号与之匹配, 那么就是 情况 1
cout << "no\n";
goto no_next;
}
cntLift --; // 出现右括号时, 若右左括号与之匹配, 则相互抵消
}
}
if (cntLift) cout << "no\n"; // 匹配结束后, 如果还有左括号没被抵消掉,那么就是 情况 2
else cout << "yes\n"; // 情况 3
no_next:;
}
return 0;
}