给出m个字符串S1,S,...,Sm和一个单独的字符串T。
请在T中选出尽可能多的子串同时满足:
这些子串在T中互不相交。
这些子串都是S1,S2,...,Sm中的某个串。
问最多能选出多少个子串。
- 输入描述
第一行一个数m(1≤m≤10),接下来m行,每行一个串。
最后一行输入一个串T。
输入中所有单个串的长度不超过100000,串中只会出现小写字母。
- 输出描述
输出一个数,最多能选出多少串。
- 示例1
输入:
3
aa
b
ac
bbaac
输出:
3
暴力求解
直接利用字符串的index方法求模式串在主串中出现的位置,再进行计算在不冲突的前提下累加的次数。这种方法居然能通过!
def find_string(string, pattern):
res = []
cur = 0
while True:
if pattern in string[cur:]:
start = string.index(pattern, cur)
end = start + len(pattern) - 1
res.append([start, end])
cur = end + 1
else:
break
return res
if __name__ == '__main__':
num = int(input().strip())
patterns = []
for _ in range(num):
patterns.append(input().strip())
string = input().strip()
res = []
for pattern in patterns:
res += find_string(string, pattern)
res.sort(key=lambda su: su[1])
pre, count = -1, 0
for ru in res:
if ru[0] > pre:
pre = ru[1]
count += 1
print(count)
使用KMP算法求子串在主串中出现的位置
依次对输入的模式串pattern通过KMP算法求出在主串string中出现的位置。得到索引位置后,对索引位置按照终止位置进行排序,再依次求不冲突的累加次数。
def kmp(string, pattern):
next_array = [0] * len(string)
def cal_next_array(pattern):
next_array[0] = -1
cursor, j = -1, 0
while j < len(pattern)-1:
if cursor == -1 or pattern[j] == pattern[cursor]:
cursor += 1
j += 1
next_array[j] = cursor
else:
cursor = next_array[cursor]
cal_next_array(pattern)
i, j = 0, 0
index = []
while i < len(string):
if j == -1 or string[i] == pattern[j]:
i += 1
j += 1
else:
j = next_array[j]
if j == len(pattern):
index.append([i-j, i-1])
j = 0
return index
if __name__ == '__main__':
num = int(input().strip())
patterns = []
for _ in range(num):
patterns.append(input().strip())
string = input().strip()
res = []
for pattern in patterns:
res += kmp(string, pattern)
res.sort(key=lambda su: su[1])
pre, count = -1, 0
for ru in res:
if ru[0] > pre:
pre = ru[1]
count += 1
print(count)
(最近更新:2019年08月28日)