在Python中,我试图从列表中提取所有包含至少4个字符的最长公共前导子字符串。例如,在下面的“数据”列表中,符合我的条件的2个最长的通用子字符串是“ johnjack”和“ detc”。我知道如何使用以下代码找到最长的公共子字符串,由于没有公共子字符串,因此未返回任何内容(按预期)。但是我正在努力构建一个可以检测列表中多个公共子字符串的脚本,其中每个公共子字符串的长度必须为4或更大。
data = ['johnjack1', 'johnjack2', 'detc22', 'detc32', 'chunganh']
def ls(data):
if len(data)==0:
prefix = ''
else:
prefix = data[0]
for i in data:
while not i.startswith(prefix) and len(prefix) > 0:
prefix = prefix[:-1]
print(prefix)
ls(data)
答案 0 :(得分:1)
这里是一个,但是我认为它可能不是最快或最有效的。让我们从答案的数据和容器开始:
data = ['johnjack1', 'johnjack2', 'detc22', 'detc32', 'chunganh', 'chunganh']
substrings = []
请注意,我为chunganh
添加了一个假名-这是我们应该处理的常见情况。
请参见How do I find the duplicates in a list and create another list with them?
因此要捕获数据中的重复项
seen = {}
dupes = []
for x in data:
if x not in seen:
seen[x] = 1
else:
if seen[x] == 1:
dupes.append(x)
seen[x] += 1
for dupe in dupes:
substrings.append(dupe)
现在让我们按原样记录数据中的唯一值
# Capture the unique values in the data
last = set(data)
从这里,我们可以遍历集合,从每个唯一值的末尾弹出字符。如果集合的长度发生变化,我们将找到一个唯一的子字符串。
# Handle strings up to 10000 characters long
for k in [0-b for b in range(1, 10000)]:
# Use negative indexing to start from the longest
last, middle = set([i[:k] for i in data]), last
# Unique substring found
if len(last) != len(middle):
for k in last:
count = 0
for word in middle:
if k in word:
count += 1
if count > 1:
substrings.append(k)
# Early stopping
if len(last) == 1:
break
最后,您提到只需要长度为4的子字符串。
list(filter(lambda x: len(x) >= 4, substrings))