最长公共子括号序列 (Python)
一个合法的括号匹配序列被定义为:
1. 空串”“是合法的括号序列
2. 如果”X”和”Y”是合法的序列,那么”XY”也是一个合法的括号序列
3. 如果”X”是一个合法的序列,那么”(X)”也是一个合法的括号序列
4. 每个合法的括号序列都可以由上面的规则生成
例如”“, “()”, “()()()”, “(()())”, “(((()))”都是合法的。
从一个字符串S中移除零个或者多个字符得到的序列称为S的子序列。
例如”abcde”的子序列有”abe”,”“,”abcde”等。
定义LCS(S,T)为字符串S和字符串T最长公共子序列的长度,即一个最长的序列W既是S的子序列也是T的子序列的长度。
小易给出一个合法的括号匹配序列s,小易希望你能找出具有以下特征的括号序列t:
1、t跟s不同,但是长度相同
2、t也是一个合法的括号匹配序列
3、LCS(s, t)是满足上述两个条件的t中最大的
因为这样的t可能存在多个,小易需要你计算出满足条件的t有多少个。
如样例所示: s = “(())()”,跟字符串s长度相同的合法括号匹配序列有:
“()(())”, “((()))”, “()()()”, “(()())”,其中LCS( “(())()”, “()(())” )为4,其他三个都为5,所以输出3.
输入描述:
输入包括字符串s(4 ≤ |s| ≤ 50,|s|表示字符串长度),保证s是一个合法的括号匹配序列。
输出描述:
输出一个正整数,满足条件的t的个数。
示例1
输入
(())()
输出
3
代码:
## 输入转为字符串
s = list(input())
## 保存 t 序列
s_set = []
length = len(s)
# 遍历序列中每个值,采用pop删除,接着用insert插入在不同位置
# 当序列合法时保存
# 合法性判断依据 无论序列多长,序列从左到右,num('(')>=num(')')始终成立
# 初始化计数器count ,当count==lenght, 数据合法,进行保存
# 即每次计数中num('(')>=num(')')成立,计数器+1,
# 最后len(t)即可
for i in range(length):
s_1 = s.copy() #初始化序列
value = s_1.pop(i) #
s_new = s_1.copy()
for j in range(length):
s_new.insert(j,value)
###判断合法性
num_left = num_right = 0
count = 0
for p in range(length):
num_left = len([x for x in s_new[:p] if x == '('])
num_right = len([x for x in s_new[:p] if x == ')'])
if num_left >= num_right:
count += 1
## 如果在每次循环中num('(')>=num(')')始终成立,则会有count=length
if count == length:
if s_new not in s_set:
s_set.append(s_new)
s_new = s_1.copy()
s_result = [s]
for i in s_set:
if i not in s_result:
s_result.append(i)
print (len(s_result)-1)