您可以拆分列表中的所有三个字符串:
list1 = list(str1)
然后list3
用你现在使用的相同算法行走,检查是否list3[i]
等于list1[0]
或list2[0]
。如果是的话,您会del
从相应的列表中获得该项目。
然后可以将过早的列表结束作为异常捕获。
该算法将完全相同,但实现应该更高性能。
更新:事实证明它实际上不是(大约两倍的时间)。哦,好吧,知道可能有用。
在对不同场景进行基准测试时,事实证明,除非指定三个字符串长度是“精确的”(即 len(p1)+len(p2) == len(p3) ),否则最有效的优化是检查第一件事。这会立即丢弃两个输入字符串由于字符串长度错误而无法匹配第三个的所有情况。
然后我遇到了一些情况,两个字符串中都有相同的字母,将它分配给 list1 或 list2 可能会导致其中一个字符串不再匹配。在这些情况下,算法会因误报而失败,这将需要递归。
def isinter(str1,str2,str3,check=True):
# print "Checking %s %s and %s" % (str1, str2, str3)
p1,p2,p3 = 0,0,0
if check:
if len(str1)+len(str2) != len(str3):
return False
while p3 < len(str3):
if p1 < len(str1) and str3[p3] == str1[p1]:
if p2 < len(str2) and str3[p3] == str2[p2]:
# does str3[p3] belong to str1 or str2?
if True == isinter(str1[p1+1:], str2[p2:], str3[p3+1:], False):
return True
if True == isinter(str1[p1:], str2[p2+1:], str3[p3+1:], False):
return True
return False
p1 += 1
elif p2 < len(str2) and str3[p3] == str2[p2]:
p2 += 1
else:
return False
p3 += 1
return p1 == len(str1) and p2 == len(str2) and p3 == len(str3)
然后我在随机字符串上运行了一些基准测试,这就是仪器(注意它总是生成有效的随机播放,这可能会产生有偏差的结果):
for j in range(3, 50):
str1 = ''
str2 = ''
for k in range(1, j):
if random.choice([True, False]):
str1 += chr(random.randint(97, 122))
if random.choice([True, False]):
str2 += chr(random.randint(97, 122))
p1 = 0
p2 = 0
str3 = ''
while len(str3) < len(str1)+len(str2):
if p1 < len(str1) and random.choice([True, False]):
str3 += str1[p1]
p1 += 1
if p2 < len(str2) and random.choice([True, False]):
str3 += str2[p2]
p2 += 1
a = time.time()
for i in range(1000000):
isShuffle2(str1, str2, str3)
a = (time.time() - a)
b = time.time()
for i in range(1000000):
isinter(str1, str2, str3)
b = (time.time() - b)
print "(%s,%s = %s) in %f against %f us" % (str1, str2, str3, a, b)
结果似乎表明缓存+DP算法对于短字符串的效率更高。当字符串变长(超过 3-4 个字符)时,缓存+DP 算法开始失势。在长度约为 10 时,上述算法的执行速度是完全递归的缓存版本的两倍。
如果字符串包含重复字符(我通过限制从 az 到 ai 的范围来做到这一点)并且重叠很小,则 DP 算法的性能更好,但仍然比上述算法差。例如,在这种情况下,DP 仅损失 2us:
(cfccha,ddehhg = cfcchaddehhg) in 68.139601 against 66.826320 us
毫不奇怪,完全重叠(每个字符串依次一个字母)的差异更大,比率高达 364:178(略高于 2:1)。