1. 问题描述:
考虑一种简单的正则表达式:只由 x ( ) | 组成的正则表达式。 小明想求出这个正则表达式能接受的最长字符串的长度。例如 ((xx|xxx)x|(x|xx))xx 能接受的最长字符串是: xxxxxx,长度是6
输入
输入一个由x()|组成的正则表达式。输入长度不超过100,保证合法
输出
输出这个正则表达式能接受的最长字符串的长度。
输入:((xx|xxx)x|(x|xx))xx
输出:6
来源:http://oj.ecustacm.cn/problem.php?id=1321
2. 思路分析:
① 分析题目可以知道题目的关键在于去除掉左右括号,当我们遇到左右括号的时候需要求解括号中表达式的值,然后根据这个括号中表达式的值进行进一步的处理,其中一个比较快速而且准确的方法是使用递归求解括号中表达式的值,利用递归往下调用返回结果这个特点来求解出括号中表达式的值(这样可以避免循环中判断字符串的值的一些操作)。我们可以这样处理:循环遍历当前的字符串,当遇到左括号的时候那么往下递归调用(递归调用的目的是为了求解括号中表达式中字符x的最大长度),返回值为括号中字符x的最大个数,可以在递归的时候使用一个局部变量c来记录当前字符x的个数(局部变量的作用是记录当前位置下记录的字符x的个数),一个用来记录当前表达式中字符x的最大长度的局部变量res,当遇到字符|的时候那么就需要更新当前表达式中字符x的最大长度并且将c置为0,c置为0的目的是为了计算字符|后面中x的长度(前面已经计算出了字符|前面表达式中字符x的最大长度了),当遇到右括号的时候说明当前括号表达式的计算已经停止,返回当前记录表达式中字符x的最大长度变量res的值到上一层中,我们需要声明一个全局变量i来记录当前递归的位置,因为这个位置在每一次递归调用的时候字符串的位置是有改变的,声明全局变量是为了可以同步修改当前递归位置的值
② 有的时候for循环中处理某些字符串匹配的时候需要使用到当前位置后面的字符串,而这个时候使用for循环 + if判断某些条件是否成立的方法是比较麻烦的,这个时候就需要考虑使用递归解决,利用递归调用返回的值可能会比较方便处理。(力扣中也有一道类似的使用递归解决字符串的匹配问题的题目,忘记是哪一道题目了)
3. 代码如下:
# i表示当前遍历到的字符串位置, c表示当前位置开始记录的字符x的最大数目
i = 0
def dfs(s: str):
global i
res, c = 0, 0
while i < len(s):
if s[i] == "(":
i += 1
c += dfs(s)
# 当前这一层表达式的值已经计算好了break或者返回当前这一层表达式中字符x的最大长度
elif s[i] == ")":
i += 1
break
# 遇到字符|那么可以更新当前记录的字符x的最大长度,将c置为0然后计算字符|后面表达值的值
elif s[i] == "|":
i += 1
res = max(res, c)
c = 0
elif s[i] == "x":
c += 1
i += 1
res = max(res, c)
return res
if __name__ == '__main__':
s = input().strip(" ")
print(dfs(s))