106.正则问题(分治)

106. 正则问题(分治)

2017年蓝桥杯省赛 - 正则问题(困难)

标签:2017 省赛 分治

题目描述

考虑一种简单的正则表达式:只由 x ( ) | 组成。小明想求出这个正则表达式能接受的最长字符串的长度。

例如 ((xx|xxx)x|(x|xx))xx 能接受的最长字符串是 xxxxxx,长度是 6。

输入描述

一个由 x ( ) | 组成的正则表达式,输入长度不超过 100,保证合法。

输出描述

这个正则表达式能接受的最长字符串的长度。

输入输出样例

示例:

输入

txt 复制代码
((xx|xxx)x|(x|xx))xx

输出

txt 复制代码
6

运行限制

  • 最大运行时间:1s
  • 最大运行内存: 256M

解题思路

表达式里只有 x ( ) | 四种符号,含义都能翻译成"长度":x 是一个字符;a|b 二选一,取较长的一支;两个部分挨在一起是连接,长度相加;() 只是分组,不影响长度。题目要的是整个表达式能拼出的最长串,所以只要按这些规则把表达式化成一个数字。

把样例 ((xx|xxx)x|(x|xx))xx 画成树,图上 | 节点两端取大、+ 节点两端相加,每个节点下方标出该子树能拼出的最长长度,根节点的 6 就是答案:

括号有嵌套,外层的长度依赖内层,所以从最内层开始化简最稳妥:反复找最里面的 (...),把它里面的内容按 | 拆开、取最长的一段替换回去,一层层把括号消掉。最后若顶层还剩 |,照样取最长的一段。

拿样例 ((xx|xxx)x|(x|xx))xx 走一遍,从最内层括号开始逐层化简:

txt 复制代码
((xx|xxx)x|(x|xx))xx
↓  最内层 (xx|xxx) 取最长,得 xxx,接上后面的 x
(xxxx|(x|xx))xx
↓  最内层 (x|xx) 取最长,得 xx
(xxxx|xx)xx
↓  括号内 xxxx|xx 取最长,得 xxxx,再接上末尾的 xx
xxxxxx   →  长度 6

代码实现

python 复制代码
s = input()


def kh(s):
    # 反复化简最内层的括号
    while ')' in s:
        r = s.find(')')  # 最靠左的右括号,它属于最内层括号
        l = r - 1
        while l >= 0:
            if s[l] == '(':  # 配对的左括号
                # 括号内按 | 拆开,取最长的一段替换回去
                p = s[l + 1: r].split('|')
                s = s[:l] + max(p, key=len) + s[r + 1:]
                break
            l -= 1
    return s


s = kh(s)

# 顶层可能还剩 |
if '|' in s:
    s = max(s.split('|'), key=len)

print(len(s))

复杂度分析

  • 时间复杂度 :O(n2)O(n^2)O(n2),nnn 是输入长度(≤100\le 100≤100)。每消掉一对括号都要做一次全串查找和拼接,最坏有 O(n)O(n)O(n) 对括号。
  • 空间复杂度 :O(n)O(n)O(n),化简过程中会不断生成新的字符串。
相关推荐
其实防守也摸鱼4 小时前
个人学习 Pwn 思路:从基础到漏洞利用的进阶路径
大数据·前端·人工智能·chrome·算法·安全·网络安全
Nuanyt5 小时前
LeetCode Hot 100 链表专题(五)· 2 题(Java)
java·算法·leetcode·链表
武天旭7 小时前
AI安全--AI大模型的毒性偏见与安全对齐实践
人工智能·python·深度学习
w_zero_one8 小时前
递归算法(一)
java·开发语言·算法
视觉小萌新8 小时前
AI Class 3 · Chapter 2-3:函数、异常、文件读写+JSON / JSONL 读写(小白版)
人工智能·python·json
小小张说故事9 小时前
Python 的 obj.x 到底按什么顺序找?拆开数据描述符、实例字典和 __getattr__ 那条优先级链
python
风影同志783249 小时前
20 个比特能装下多少行情?——实测拆解 Kronos 的 K 线分词器
算法
写的都是BUG10 小时前
APK 里的钥匙,一直就放在门口:聊聊加固真正该做什么
前端·算法
用户114818678948410 小时前
水印的实现方式逻辑
前端·python