我有一个存储在远程数据库中的项目列表,这些项目可能是未排序的,我想对它们进行排序。数据库接受以下命令:
move item1 before item2
move item3 after item2
所以,给出一个表格列表:
[1,3,2,7,6,0,4]
......我怎样才能得到一系列动作:
move 2 before 3
move 7 after 6
move 0 before 1
move 4 before 6
我假设对bubblesort算法的修改可行,但我特别寻找仍然是pythonic的最有效的实现,并且生成最少的移动命令。
更新:列表长度为1000-10000,所有项目都是唯一的 - 没有重复。只有极少数项目 - 1-10 - 在任何给定时间都会出错。时间是一个值得关注的问题 - 它需要几秒钟,而不是几分钟 - 但它不必非常非常。
更新2:我还想只移动一次项目
答案 0 :(得分:3)
由于你想减少移动序列的数量,我能想到的最佳方法是在排序列表上使用二进制搜索来确定每个元素的插入点。如果任何元素已经处于正确位置,则无需移动它。
这将生成n - d
个序列移动,其中n
是元素数量,d
是元素数量正确的位置。
n - d = n - n = 0
n - d = n - 0 = n
<强>实施强>
def gen_move(seq):
from bisect import bisect_left
out = seq[0:1]
for elem in seq[1:]:
index = bisect_left(out, elem)
if seq[index] != elem:
if index == 0:
print "Move {} before {}".format(elem, out[index])
else:
print "Move {} after {}".format(elem, out[index - 1])
out.insert(index, elem)
print out
<强>演示强>
gen_move([1,3,2,7,6,0,4])
Move 2 after 1
Move 6 after 3
Move 0 before 1
Move 4 after 3
[0, 1, 2, 3, 4, 6, 7]
gen_move(range(10)[::-1])
Move 8 before 9
Move 7 before 8
Move 6 before 7
Move 5 before 6
Move 4 before 5
Move 3 before 4
Move 2 before 3
Move 1 before 2
Move 0 before 1
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
gen_move(range(10))
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
<强>性能强>
In [5]: %timeit gen_move(range(10000, 0, -1))
10000 loops, best of 3: 84 us per loop
时间复杂度
sum(1 ln 1 + 2 ln 2 + 3 ln 3 + ..... n ln n) < O(n ln n)
空间复杂性
O(n)
答案 1 :(得分:2)
sort
)我有点担心difflib的时间复杂性,所以你应该根据预期的数据大小进行基准测试。更快的替代方案可能是滚动校验和算法(如librsync)。
答案 2 :(得分:1)
这很天真,但似乎有效:
xs = [1,3,2,7,6,0,4]
ys = []
for x in xs:
for n, y in enumerate(ys):
if x < y:
print x, 'before', y
ys.insert(n, x)
break
else:
ys.append(x)
结果:
2 before 3
6 before 7
0 before 1
4 before 6