深圳大学 数据结构OJ—串应用(Python)
前言
本文是深圳大学数据结构实验课的一些记录,考虑到现在这门课基本没有Python版本的题解。所以特此整理出来,让Python programmer也可以更好地掌握这门课的内容。同时也是督促自己更高质量地完成实验。
A. DS串应用–KMP算法
题目描述
学习KMP算法,给出主串和模式串,求模式串在主串的位置
输入
第一个输入t,表示有t个实例
第二行输入第1个实例的主串,第三行输入第1个实例的模式串
以此类推
输出
第一行输出第1个实例的模式串的next值
第二行输出第1个实例的匹配位置,位置从1开始计算,如果匹配成功输出位置,匹配失败输出0
以此类推
题解
def get_next(pattern):
# 生成next数组
# next[i]表示pattern[0:i]的最长公共前后缀长度
# next[0] = -1
next = [-1] * len(pattern)
i = 0
j = -1
while i < len(pattern) - 1:
if j == -1 or pattern[i] == pattern[j]:
i += 1
j += 1
next[i] = j
else:
j = next[j]
return next
def kmp(string, pattern):
# KMP算法
next = get_next(pattern)
i = 0
j = 0
while i < len(string) and j < len(pattern):
if j == -1 or string[i] == pattern[j]:
i += 1
j += 1
else:
j = next[j]
if j == len(pattern):
return i - j + 1
else:
return 0
if __name__ == '__main__':
t = int(input())
for _ in range(t):
string = input()
pattern = input()
next = get_next(pattern)
print(' '.join(map(str, next)) + ' ')
print(kmp(string, pattern))
B. DS串应用–串替换
题目描述
给出主串、模式串、替换串,用KMP算法找出模式串在主串的位置,然后用替换串的字符替换掉模式串
本题只考虑一处替换的情况,如果你想做的完美一些,能够实现多处替换那
可能需要考虑模式串和替换串长度不一致的情况
输入
第一个输入t,表示有t个实例
第二行输入第1个实例的主串,第三行输入第1个实例的模式串,第四行输入第1个实例的替换串
以此类推
输出
第一行输出第1个实例的主串
第二行输出第1个实例的主串替换后结果,如果没有发生替换就输出主串原来的内容。
以此类推
题解
def get_next(pattern):
next = [-1] * len(pattern)
i = 0
j = -1
while i < len(pattern) - 1:
if j == -1 or pattern[i] == pattern[j]:
i += 1
j += 1
next[i] = j
else:
j = next[j]
return next
def kmp(string, pattern):
next = get_next(pattern)
i = 0
j = 0
while i < len(string) and j < len(pattern):
if j == -1 or string[i] == pattern[j]:
i += 1
j += 1
else:
j = next[j]
if j == len(pattern):
return i - j + 1
else:
return 0
def replace(string, pattern, new):
if kmp(string, pattern):
loc = kmp(string, pattern)
return string[:loc-1] + new + string[loc+len(pattern)-1:]
else:
return string
if __name__ == '__main__':
t = int(input())
for _ in range(t):
string = input()
pattern = input()
new = input()
print(string)
print(replace(string, pattern, new))
C. 串应用- 计算一个串的最长的真前后缀
题目描述
给定一个串,如ABCDAB,则ABCDAB的真前缀有:{ A, AB,ABC, ABCD, ABCDA }ABCDAB的真后缀有:{ B, AB,DAB, CDAB, BCDAB } 因此,该串的真前缀和真后缀中最长的相等串为AB,我们称之为该串的“最长的真前后缀”。试实现一个函数string matched_Prefix_Postfix(string str),得到输入串str的最长的真前后缀。若不存在最长的真前后缀则输出empty
输入
第1行:串的个数 n第2行到第n+1行:n个字符串
输出
n个最长的真前后缀,若不存在最长的真前后缀则输出empty。
题解
t = int(input())
for _ in range(t):
string = input()
sub = 'empty'
for l in range(1, len(string)):
if string[:l] == string[len(string)-l:]:
sub = string[:l]
print(sub)
D. DS串应用—最长重复子串
题目描述
求串的最长重复子串长度(子串不重叠)。例如:abcaefabcabc的最长重复子串是串abca,长度为4。
输入
测试次数t
t个测试串
输出
对每个测试串,输出最长重复子串长度,若没有重复子串,输出-1
题解
def max_sub_str(s):
n = len(s)
max_len = 0
for i in range(n):
for j in range(i+1, n):
if s[i] == s[j]:
k = 1
while i+k < n and j+k < n and i+k < j and s[i+k] == s[j+k]:
k += 1
if k > max_len:
max_len = k
if max_len ==0:
return -1
return max_len
if __name__ == '__main__':
t = int(input())
for _ in range(t):
s = input()
print(max_sub_str(s))
E. 可重叠子串 (Ver. I)
题目描述
给定一个字符串(模式串)和一些待查找的字符串,求每个待查找字符串在模式串中出现的次数(可重叠)
输入
第一行输入t,表示有t组测试数据
每一组测试数据包含多行:
每一组的第一行包括一个字符串P,长度不超过105,且非空串
每一组的第二行包括一个整数N,代表待查找的字符串数量 (1 <= N <= 5)
每一组接下来的N行,每一行包括一个待查找的字符串,其长度不超过50,且非空串
输出
对于每组测试数据,
输出每个待查找字符串出现的次数,
具体输出见样例
题解
def search(pattern, string):
count = 0
for i in range(len(string) - len(pattern) + 1):
if string[i:i + len(pattern)] == pattern:
count += 1
return count
t = int(input())
for _ in range(t):
string = input()
n = int(input())
for _ in range(n):
pattern = input()
print(pattern + ':' + str(search(pattern, string)))