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),化简过程中会不断生成新的字符串。
相关推荐
All for pursuit.1 小时前
【位运算-3】136.只出现一次的数字
数据结构·c++·算法·leetcode
Pingred1 小时前
我把一个私有化 RAG 系统真正跑通了:LocalRAG v0.1.0 发布
人工智能·python
suhan1 小时前
【数据结构】五、树:7.哈夫曼树、哈夫曼编码
数据结构·算法·排序算法
Dmz丶1 小时前
前端转 AI 100 天 Day 24:API 测试——用 httpx + pytest 测 FastAPI
python
kkhimself1 小时前
POJ-3126
算法
suhan2 小时前
【数据结构】五、树:6.平衡二叉树AVL
数据结构·算法·排序算法
东莞市云毅网络有限公司2 小时前
监测问句清单去重:停用词表、数字归一与贪心聚类的参数取法
python·数据清洗·rag·企业知识库·文档解析
suhan2 小时前
【数据结构】五、树:5.二叉排序树BST
数据结构·算法·排序算法
爱读书的小胖2 小时前
80. 删除有序数组中的重复项 II
java·数据结构·算法