这里解决这个问题是使用NumPy
一个量化的方法 -
import numpy as np
def in_string(s1,s2):
arr1 = np.fromstring(s1, dtype=np.uint8)
arr2 = np.fromstring(s2, dtype=np.uint8)
return np.in1d(arr1,arr2).all()
采样运行 -
In [50]: in_string('hypochondriac','yqhpwoewnqlchpijcdrxpoa')
Out[50]: True
# Let's add in a `z` at the end of first word which isn't in the scramble
In [51]: in_string('hypochondriacz','yqhpwoewnqlchpijcdrxpoa')
Out[51]: False
这里的另一个NUMP基于Y的一个使用np.searchsorted
-
def in_string_v2(s1,s2):
arr1 = np.fromstring(s1, dtype=np.uint8)
arr2 = np.fromstring(s2, dtype=np.uint8)
u1 = np.unique(arr1)
u2 = np.unique(arr2)
return ~(np.searchsorted(u2,u1) == np.searchsorted(u2,u1,'right')).any()
这里是另外一个,一次处理一个单词列表中一个违背一个争夺 -
def in_string_v3(list_s1,s2):
l_arr1 = np.fromstring("".join(list_s1), dtype=np.uint8)
arr2 = np.fromstring(s2, dtype=np.uint8)
lens = np.array(map(len,list_s1))
comp_lens = np.in1d(l_arr1,arr2).cumsum()[lens.cumsum()-1]
calc_lens = np.append(comp_lens[0],comp_lens[1:]-comp_lens[:-1])
return lens == calc_lens
采样运行 -
In [185]: ls1 = ['hypochondriac','hypochondriachsdhsahdsadhsa','hihfheifheozz']
In [186]: s2 = 'yqhpwoewnqlchpijcdrxpoadjksdgdkjsfkbdsfbdsdsaduiawyei'
In [187]: in_string_v3(ls1,s2)
Out[187]: array([ True, True, False], dtype=bool)
还有一个以不同的方式处理单词列表 -
def in_string_v4(list_s1,s2):
l_arr1 = np.fromstring("".join(list_s1), dtype=np.uint8)
arr2 = np.fromstring(s2, dtype=np.uint8)
lens = np.array(map(len,list_s1))
clens = lens.cumsum()
non_matching_idx = np.nonzero(~np.in1d(l_arr1,arr2))[0]
non_matching_grp = np.unique(clens.searchsorted(non_matching_idx))
return ~np.in1d(np.arange(len(list_s1)),non_matching_grp)
感谢您的帮助!我做了这些改变并测试了这些方法,结果只有轻微的性能提升。我想我看到的表现来自不太明显的地方。 – user1362058
@ user1362058:你在Python 2上吗?计数时,2.7上的Counter()会有点慢,这可能会影响性能。 Python 3增加了C优化来解决这个问题。 –
@ user1362058:然而,对于大字符串,您应该在2.7上看到Counter win,因为您的方法渐近地变慢(O(NM)vs O(N + M))。 –