目录
时间限制: 3s 内存限制: 192MB 提交: 1157 解决: 390
题目描述
考虑一种简单的正则表达式:
只由 x ( ) | 组成的正则表达式。
小明想求出这个正则表达式能接受的最长字符串的长度。
例如 ((xx|xxx)x|(x|xx))xx 能接受的最长字符串是: xxxxxx,长度是6。
输入格式
一个由x()|组成的正则表达式。输入长度不超过100,保证合法。
输出格式
这个正则表达式能接受的最长字符串的长度。
样例输入
((xx|xxx)x|(x|xx))xx
样例输出
6
原题地址
题目解释
(1)先看第一个括号,发现里面还嵌套了括号,找到最内部的括号,括号内是一个或操作。
(xxx)l(x)xx,得: (xxx(l}x))xx。
(2)执行最内部的括号。(xxx|(x|xx))xx, 得: (xxxx)xx)xx。
(3)执行最后的括号。(xxxx{|xx)xx, 得: xXXXXx。 结束,得到长度为6的字符串。
本题是练习DFS (递归)和栈的好题目。
题目的主体是括号匹配,这是经典的递归、栈的应用。
(1)一个左括号必然与- -个右括号匹配。读者可以尝试生成各种各样的嵌套括号,方法是:从第1对括
号“0”开始,把第2对括号的左括号和右括号分别随机插入第1对括号中的任意位置,例如"()" ;
再把第3对括号随机插入,例如"())”,等等。只要括号是成对插入的,得到的括号串就都是合法
的。
(2)用栈检查括号的合法性。每遇到一个左括号“(”,就入栈,每遇到-一个右括号“)”,就完成一
次匹配,出栈。读者可以用一个嵌套括号来练习-下。
(3)编程。可以直接用栈编程,也可以用DFS (递归)编程,后者更简单。
本题的字符串除了括号,还有"|”和"x”。"”和“x”的处理与括号的递归处理有关,这使得代
码的逻辑有点复杂。
代码思路如下
import java.util.Scanner;
public class Main {
static String string;
// 用静态变量当做string这个数中每个字符串的索引 使用string.charAt(索引)这个方法
static int zb;
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
string = scanner.next();
System.out.println(dfs());
}
// 使用大法师
static int dfs() {
// 这个是遇到'|'时寄存tmp 让tmp接收新值 还有就是与tmp作Math.max取大的值
int ans = 0;
// 搜集x的数量的
int tmp = 0;
// 字符串的长度
int len = string.length();
while (len > zb) {
if (string.charAt(zb) == '(') {
// 每进入一个if 都要把索引多加一
zb++;
// 遇到'('相当于 这个dfs()只管以这个'('开头的括号 里的正则表达式代表的x数 是用tmp来记录x的 所以要用tmp来加 这一块的x个数
tmp += dfs();
} else if (string.charAt(zb) == ')') {
// 每进入一个if 都要把索引多加一
zb++;
// '('和')'是一对 有这个')'出现代表退出 以')'结尾的dfs()
break;
} else if (string.charAt(zb) == '|') {
// 每进入一个if 都要把索引多加一
zb++;
// 如果有这样的情况"x|xx|xxx|x"则可取出其中最多x数
ans = Math.max(tmp, ans);
// tmp是搜集个个分开的x的个数 遇到'|'就可以将搜集到的值赋给 ans 自己赋值为0方便搜集下一块的x个数
tmp = 0;
} else if (string.charAt(zb) == 'x') {
// 每进入一个if 都要把索引多加一
zb++;
// 有x temp变量就要多一个
tmp++;
}
}
// 到')'就break到这里了(意思是退出了'('')'这个) 如果'('和')'前面有'|'可以做出正则判断
ans = Math.max(tmp, ans);
return ans;
}
}