我正在制作一个接收电话号码列表的代码,然后检查一个或多个号码是否是列表中其他号码的前缀。我想优化到最大,以便它可以尽可能快地运行。这是代码:
cases = []
t = int(input())
for i in range(0, t):
n = int(input())
case = []
for j in range(0, n):
case.append(str(input()))
cases.append(sorted(case))
print(cases)
for c in cases:
answer = 'YES'
for k in range(0, len(c)):
if answer == 'YES':
for l in range(0, len(c)):
if c[k] != c[l]:
if c[k] == c[l][0:len(c[k])]:
answer = 'NO'
break
else:
break
print(answer)
编辑:使用@Gelineau提出的答案,代码运行在0.82秒,即从> 3s到达解决方案之前。现在,解决方案看起来像这样:
cases = []
t = int(input())
for i in range(0, t):
n = int(input())
case = []
for j in range(0, n):
case.append(str(input()))
cases.append(case)
for case in cases:
answer = 'YES'
case.sort()
for case_k, case_next in zip(case, case[1:]):
if case_k == case_next[:len(case_k)]:
answer = 'NO'
break
print(answer)
答案 0 :(得分:1)
如果你希望它非常快,那么python很可能不是正确的选择。但你可以做一些小改动,而不是
for i in range(len(c):
use c[i] ...
你可以使用
for i in range(len(c):
use i ...
同样answer == 'YES'
将永远为真,因为当你使它变为假时你会刹车。我最终将代码缩减到了这个:
for case in cases:
answer = 'YES'
for case_k, case_l in product(case,case):
if case_k != case_l and case_k == case_l[:len(case_k)]:
answer = 'NO'
break
print(answer)
你无法真正加速IO,你可以将其改为列表类,但你并没有真正获得任何东西,而且可读性受到很大影响:
cases = [sorted([str(input()) for _ in range(int(input()))]) for _ in range(int(input()))]
编辑:根据@Gelineau留下的评论,我以为我会再给它一次。
但它仍然在O(n ^ 2)时间内增长。
cases = ["".join([input() for _ in range(int(input()))]) for _ in range(int(input()))]
#cases = ['123', '4321', '12345']
for i,case_a in enumerate(cases):
for case_b in cases[i+1:]:
if case_b.startswith(case_a):
print(case_a, "is a prefix")
break
else:
print(case_a, "is not a prefix")
答案 1 :(得分:0)
IMO,由于列表已排序,您可以直接将相邻记录与一个循环进行比较
['2345','1234','123','4567','12345','21234'] => ['123', '1234', '12345', '21234', '2345', '4567']
如果前一记录长度小于当前记录长度且当前第一个X值等于前一记录长度。然后找到并休息。
谢谢