2017级第二次上机之W型串

题目描述

W型串
一个由括号构成的字符串称为W型串(W-string),当且仅当该串可以表示为(A)或(A)(B)的形式,其中A,B是空串或W型串.

例如()、((()))、(())()等是W型串,而()()()、(()(())())等不是W型串. 给出n个由括号构成的非空字符串,判断每个串是否为W型串.


输入

第一行为一个正整数n,表示需判断的字符串个数. 接下来n行,每行一个仅由左右括号(ASCII码分别为40和41)构成的非空字符串S.

0 < |S| <= 1000; n <= 100.


输出

输出n行,分别对应每个字符串是否为W型串,如果是则输出Yes,否则输出No.


输入样例

8
(((((())))))
))()(
((((()
(()(()))
((()())(()()))((()())(()()))
(()(())()((())))()
((())(()))((())(()))
(((()()(((()))))))

输出样例

Yes
No
No
Yes
Yes
No
Yes
No

解题思路

W型串这个定义本来就是递归定义的,所以自然想到要递归的处理首先考虑几个基本的情况

  1. 如果这个串是空的,显然是W型串
  2. 如果这个串一开始不是(,显然不是W型串
  3. 如果这个串不以)结尾,显然也不是W型串

那么,我们可以借鉴括号匹配的思路,把所给的串拆成若干个括号匹配的序列然后分别判断它是不是W型串。如果括号匹配的话我们把这个串的第一个括号和最后一个括号都去掉,然后判断去掉括号的序列是不是W型串,这样一直递归下去判断即可。我这里用了substr函数取子串其实大可不必这样,可以直接在函数参数里指定起始结束位置。


AC代码

#define _CRT_SECURE_NO_WARNINGS
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <vector>
#include <cstdlib>
#include <map>
#include <string>
#include <cmath>
#include <cctype>
#include <stack>
#include <queue>
#include <climits>
#include <set>
using namespace std;
int n;
bool judge(string s) {
	if (s.empty()) return true;
	if (s[0] != '(') return false;
	if (s[s.length() - 1] != ')') return false;
	if (s[0] == '('&&s[1] == ')'&&s.length()==2) return true;
	stack<char> S;
	while (!S.empty()) S.pop();
	int i;
	for ( i = 0; i < s.length(); i++) {
		if (s[i] == '(') S.push(s[i]);
		else S.pop();
		if (S.empty()) {
			if (i == s.length() - 1) i++;
			break;
		}
	}
	if (!S.empty()) return false;
 	if (i == s.length()) {
		string tmp = s.substr(1, i - 2);
		return judge(tmp);
	}
	else {
		int ii = s.length() - 2;
		string tmp = s.substr(1, i - 1);
		string tmpp = s.substr(i + 2);
		tmpp.erase(tmpp.length() - 1);
		return(judge(tmp) && judge(tmpp));
	}

}
int main() {
	//freopen("Text.txt", "r", stdin);
	scanf("%d", &n);
	while (n--) {
		string s1;
		cin >> s1;
		if (judge(s1)) printf("Yes\n");
		else printf("No\n");
	}
	return 0;
}

小结

解决结构一样只是规模不一样的问题用递归最好辣

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值