我需要找到两个字符串之间的交集。 断言:
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
参数,w
和w2
列表理解。迭代并在第二个字符串中查找出现的地方。
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
可行,但是有人能想到更好的,优化的方法吗?
编辑: 该函数将返回一个字符列表。顺序并不重要。
答案 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})