【问题标题】:Common substring in list of strings字符串列表中的公共子字符串
【发布时间】:2021-05-19 17:20:49
【问题描述】:

我在尝试解决给定一些字符串及其长度的问题时遇到了一个问题,您需要找到它们的公共子字符串。我的代码循环遍历列表,然后每个单词遍历其中的每个单词是这样的:

num_of_cases = int(input())
for i in range(1, num_of_cases+1):
    if __name__ == '__main__':
        len_of_str = list(map(int, input().split()))
        len_of_virus = int(input())

    strings = []
    def string(strings, len_of_str):
        len_of_list = len(len_of_str)
        for i in range(1, len_of_list+1):
            strings.append(input())
    
    lst_of_subs = []
    virus_index = []
    def substr(strings, len_of_virus):
        for word in strings:
             for i in range(len(len_of_str)):
                  leng = word[i:len_of_virus]
                  lst_of_subs.append(leng)
                  virus_index.append(i)

    print(string(strings, len_of_str))
    print(substr(strings, len_of_virus))

给定字符串,它会打印以下内容:ananasso、associazione、tassonomia、massone

['anan', 'nan', 'an', 'n', 'asso', 'sso', 'so', 'o', 'tass', 'ass', 'ss', 's', 'mass', 'ass', 'ss', 's']

似乎结束索引没有增加,虽然我尝试在循环结束时写len_of_virus += 1

样本输入:

1
8 12 10 7
4
ananasso
associazione
tassonomia
massone

其中第一个字母是病例数,第二行是字符串的名称,第三个是病毒的长度(公共子字符串),然后是我应该循环遍历的给定字符串。

预期输出:

Case #1: 4 0 1 1

其中四个数字是公共子字符串的起始索引。(我不认为打印代码关心我们这个特殊问题)

我该怎么办?请帮忙!!

【问题讨论】:

  • 好吧,我决定不放函数头,这会影响输出吗?输入是:8 12 10 7 4 ananasso associazione tassonomia massone 它应该打印出公共子字符串 'asso' 以及它在列表的每个字符串中的起始索引(前 4 个数字是列表中的字符串,第 5 个数字是病毒的长度,也就是公共子字符串,四个字符串是我必须循环的)
  • 我编辑了帖子并添加了 func 标题
  • 病毒在问题陈述中,它说每个字符串中都有一个病毒(一个子字符串),并且每个字符串中的长度相同。我的任务是找到该病毒(每个字符串中的公共子字符串并打印出每个字符串中的起始索引)
  • 好的,谢谢。我找到了problem statement(第 5 页)
  • 是的,我想就是这样,虽然我找到的链接是this

标签: python python-3.x algorithm substring python-3.8


【解决方案1】:

首先从最短的字符串中提取给定大小的所有子字符串。然后选择所有字符串中存在的第一个子字符串。最后输出这个公共子串在每个字符串中的位置:

def commonSubs(strings,size):
    base = min(strings,key=len) # shortest string
    subs = [base[i:i+size] for i in range(len(base)-size+1)] # all substrings
    cs = next(ss for ss in subs if all(ss in s for s in strings)) # first common
    return [s.index(cs) for s in strings] # indexes of common substring

输出:

S = ["ananasso", "associazione", "tassonomia", "massone"]
print(commonSubs(S,4))
[4, 0, 1, 1]

您也可以使用递归方法:

def commonSubs(strings,size,i=0):
    sub = strings[0][i:i+size]
    if all(sub in s for s in strings):
        return [s.index(sub) for s in strings]
    return commonSubs(strings,size,i+1)

【讨论】:

    【解决方案2】:

    除了在奇怪的地方定义函数并使用所述函数以不真正鼓励的方式获得副作用之外,问题就在这里:

    for i in range(len(len_of_str)):
        leng = word[i:len_of_virus]
    

    i 在每次迭代中不断增加,但 len_of_virus 保持不变,所以你正在有效地做

    word[0:4] #when len_of_virus=4
    word[1:4]
    word[2:4]
    word[3:4]
    ...
    

    这就是'anan', 'nan', 'an', 'n', 来自第一个单词“ananasso”的地方,另一个也一样

    >>> word="ananasso"
    >>> len_of_virus = 4
    >>> for i in range(len(word)):
            word[i:len_of_virus]
    
        
    'anan'
    'nan'
    'an'
    'n'
    ''
    ''
    ''
    ''
    >>> 
    

    你可以修复它,将上端移动 i,但在另一端留下同样的问题

    >>> for i in range(len(word)):
        word[i:len_of_virus+i]
    
        
    'anan'
    'nana'
    'anas'
    'nass'
    'asso'
    'sso'
    'so'
    'o'
    >>>
    

    所以在范围和问题解决一些简单的调整:

    >>> for i in range(len(word)-len_of_virus+1):
            word[i:len_of_virus+i]
    
        
    'anan'
    'nana'
    'anas'
    'nass'
    'asso'
    >>> 
    

    既然子字符串部分已经完成,剩下的也很简单了

    >>> def substring(text,size):
            return [text[i:i+size] for i in range(len(text)-size+1)]
    
    >>> def find_common(lst_text,size):
            subs = [set(substring(x,size)) for x in lst_text]
            return set.intersection(*subs)
    
    >>> test="""ananasso
    associazione
    tassonomia
    massone""".split()
    >>> find_common(test,4)
    {'asso'}
    >>> 
    

    要找到列表中所有字符串的共同部分,我们可以使用set,首先我们将给定单词的所有子字符串放入一个集合中,最后将它们全部相交。

    剩下的就是根据自己的喜好打印出来

    >>> virus = find_common(test,4).pop()
    >>> print("case 1:",*[x.index(virus) for x in test])
    case 1: 4 0 1 1
    >>> 
    

    【讨论】:

    • 基本上我应该用函数(子字符串)替换我的 for 循环吗?此外,它会打印出交集需要参数的错误。
    • 基本上是的,这里的想法是使用我在此处介绍的内容,然后您使用这些想法并对其进行调整以修复您的代码...我不知道您为什么会收到该错误,因为我不知道你到底在做什么
    • 好的,谢谢,我终于明白了:-)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-29
    • 2023-03-28
    • 2019-10-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多