使用蛮力在python 3中查找字符串中的所有子字符串

时间:2018-10-11 17:30:36

标签: python string python-3.x substring brute-force

我想用蛮力在'A' to 'B'中找到所有子串L = ['C', 'A', 'B', 'A', 'A', 'X', 'B', 'Y', 'A'],这就是我所做的:

def find_substring(L):
    t = 0
    s = []
    for i in range(len(L) - 1):
        l = []
        if ord(L[i]) == 65:
            for j in range(i, len(L)):
                l.append(L[j])
                if ord(L[j]) == 66:
                    t = t + 1
                    s.append(l)
    return s, t

现在我想要输出:

[['A','B'], ['A','B','A','A','X','B'], ['A','A','X','B'], ['A','X','B']]

但是我得到:

[['A','B','A','A','X','B','Y','A'],['A','B','A','A','X','B','Y','A'],['A','A','X','B','Y','A'],['A','X','B','Y','A']]

有人可以告诉我我在做什么错吗?

6 个答案:

答案 0 :(得分:4)

问题在于列表s包含对l列表的引用。

因此,即使您将正确的l列表追加到s,它们也将在追加后更改,因为j循环的未来迭代会修改l列表

您可以通过附加l列表的副本l[:]来解决此问题。

此外,您可以直接比较字符串,而无需转换为ASCII。

def find_substring(L):
    s = []
    for i in range(len(L) - 1):
        l = []
        if L[i] == 'A':
            for j in range(i, len(L)):
                l.append(L[j])
                if L[j] == 'B':
                    s.append(l[:])
    return s

现在可以使用:

>>> find_substring(['C', 'A', 'B', 'A', 'A', 'X', 'B', 'Y', 'A'])
[['A', 'B'], ['A', 'B', 'A', 'A', 'X', 'B'], ['A', 'A', 'X', 'B'], ['A', 'X', 'B']]

答案 1 :(得分:1)

在将l附加到s时,您是在列表中添加引用,然后列表会继续增长。您想在添加时添加l列表内容的副本,以使其保持静态。

           s.append(l[:])

这是常见的常见问题解答;这个问题可能应该作为重复项关闭。

答案 2 :(得分:1)

最好先找到'A''B'的所有索引,然后遍历所有索引,以避免蛮力。

def find_substrings(lst)
    idx_A = [i for i, c in enumerate(lst) if c == 'A']
    idx_B = [i for i, c in enumerate(lst) if c == 'B']

    return [lst[i:j+1] for i in idx_A for j in idx_B if j > i]

答案 3 :(得分:0)

您可以在最后一次追加之后将{追加到l之后将l = l[:]重置为字符串的副本。

答案 4 :(得分:0)

那么,您想要所有以'A'开头并以'B'结尾的子字符串吗?

使用@Joeidden的代码时,您可以将for i in range(len(L) - 1):更改为for i in range(len(L)):,因为只有以'B'结尾的字符串将附加到s

def find_substring(L):
    s = []
    for i in range(len(L)):
        l = []
        if L[i] == 'A':
            for j in range(i, len(L)):
                l.append(L[j])
                if L[j] == 'B':
                    s.append(l[:])
return s

答案 5 :(得分:0)

另一种稍微不同的方法是:

L = ['C', 'A', 'B', 'A', 'A', 'X', 'B', 'Y', 'A']

def find_substring(L):
    output = []
    # Start searching for A.
    for i in range(len(L)):
        # If you found one start searching all B's until you reach the end.
        if L[i]=='A':
            for j in range(i,len(L),1):
                # If you found a B, append the sublist from i index to j+1 index (positions of A and B respectively).
                if L[j]=='B':
                    output.append(L[i:j+1])
    return output

result = find_substring(L)
print(result)

输出:

[['A', 'B'], ['A', 'B', 'A', 'A', 'X', 'B'], ['A', 'A', 'X', 'B'], ['A', 'X', 'B']]

如果您需要上述列表的理解:

def find_substring(L):
    output = [L[i:j+1] for i in range(len(L)) for j in range(i,len(L),1) if L[i]=='A' and L[j]=='B']
    return output