找到两个字符串之间的交点的最佳方法是什么?

时间:2018-08-08 14:13:28

标签: python string performance set

我需要找到两个字符串之间的交集。 断言:

assert intersect("test", "tes") == list("tes"), "Assertion 1"
assert intersect("test", "ta") == list("t"), "Assertion 2"
assert intersect("foo", "fo") == list("fo"), "Assertion 3"
assert intersect("foobar", "foo") == list("foo"), "Assertion 4"

我为intersect函数尝试了不同的实现。 intersect将收到2个str参数,ww2


列表理解。迭代并在第二个字符串中查找出现的地方。

return [l for l in w if l in w2]

失败断言1和2,因为w中的多个 t w2中的一个 t 匹配


设置相交。

return list(set(w).intersection(w2)
return list(set(w) & set(w2))

失败断言3和4,因为集合是collection of unique elements,重复的字母将被丢弃。


迭代并计数。

out = ""
for c in s1:
    if c in s2 and not c in out:
        out += c
return out

失败,因为它还会消除重复项。


difflib Python Documentation

letters_diff = difflib.ndiff(word, non_wildcards_letters)
letters_intersection = []

for l in letters_diff:
    letter_code, letter = l[:2], l[2:]
    if letter_code == "  ":
        letters_intersection.append(letter)

return letters_intersection

通过


difflib可行,但是有人能想到更好的,优化的方法吗?

编辑: 该函数将返回一个字符列表。顺序并不重要。

3 个答案:

答案 0 :(得分:2)

尝试一下:

BasePage<UserControl>

注意:它不会保留顺序(如果我没记错def intersect(string1, string2): common = [] for char in set(string1): common.extend(char * min(string1.count(char), string2.count(char))) return common ,字母将按字母顺序返回)。但是,正如您在评论中所说,顺序并不重要

答案 1 :(得分:1)

这对于您的测试用例非常有效:

A

但是,请记住,您的所有测试用例要长而短,没有空的搜索词,空的搜索空间或不匹配的内容。

答案 2 :(得分:0)

给出两个字符串中所有n-gram的共现次数:

from collections import Counter

def all_ngrams(text):
    ngrams = ( text[i:i+n] for n in range(1, len(text)+1)
                           for i in range(len(text)-n+1) )
    return Counter(ngrams)

def intersection(string1, string2):
    count_1 = all_ngrams(string1)
    count_2 = all_ngrams(string2)
    return count_1 & count_2   # intersection:  min(c[x], d[x])

intersection('foo', 'f') # Counter({'f': 1})
intersection('foo', 'o') # Counter({'o': 1})
intersection('foobar', 'foo') # Counter({'f': 1, 'fo': 1, 'foo': 1, 'o': 2, 'oo': 1})
intersection('abhab', 'abab') # Counter({'a': 2, 'ab': 2, 'b': 2})
intersection('achab', 'abac') # Counter({'a': 2, 'ab': 1, 'ac': 1, 'b': 1, 'c': 1})
intersection('test', 'ates') # Counter({'e': 1, 'es': 1, 's': 1, 't': 1, 'te': 1, 'tes': 1})