当前位置:  开发笔记 > 编程语言 > 正文

连接两个排序的整数列表的更好方法

如何解决《连接两个排序的整数列表的更好方法》经验,为你挑选了1个好方法。

假设我有一个列表和另一个元组,它们都已经排序:

A = [10, 20, 30, 40]
B = (20, 60, 81, 90)

我需要的是将A中的所有元素添加到A中,使A保持排序.

我可以带来的解决方案是:

for item in B:
    for i in range(0, len(A)):
        if item > A[i]:
            i += 1
        else: 
            A.insert(i, item)

假设大小为A的A和大小为n的B; x在最坏的情况下,这个解决方案需要O(m n),我怎样才能让它表现更好?



1> Padraic Cunn..:

一个简单的方法是heapq.merge:

A = [10, 20, 30, 40]

B = (20, 60, 81, 90)

from heapq import merge

for ele in merge(A,B):
    print(ele)

输出:

10
20
20
30
40
60
81
90

使用其他O(n)解决方案的一些时间:

In [53]: A = list(range(10000))

In [54]: B = list(range(1,20000,10))

In [55]: timeit list(merge(A,B))
100 loops, best of 3: 2.52 ms per loop

In [56]: %%timeit
C = []
i = j = 0
while i < len(A) and j < len(B):
    if A[i] < B[j]:
        C.append(A[i])
        i += 1
    else:
        C.append(B[j])
        j += 1
C += A[i:] + B[j:]
   ....: 
100 loops, best of 3: 4.29 ms per loop
In [58]: m =list(merge(A,B))
In [59]: m == C
Out[59]: True

如果你想自己动手,这比合并要快一些:

def merger_try(a, b):
    if not a or not b:
        yield chain(a, b)
    iter_a, iter_b = iter(a), iter(b)
    prev_a, prev_b = next(iter_a), next(iter_b)
    while True:
        if prev_a >= prev_b:
            yield prev_b
            try:
                prev_b = next(iter_b)
            except StopIteration:
                yield prev_a
                break
        else:
            yield prev_a
            try:
                prev_a = next(iter_a)
            except StopIteration:
                yield prev_b
                break
    for ele in chain(iter_b, iter_a):
        yield ele

一些时间:

In [128]: timeit list(merge(A,B))
1 loops, best of 3: 771 ms per loop

In [129]: timeit list(merger_try(A,B))
1 loops, best of 3: 581 ms per loop

In [130]: list(merger_try(A,B))  == list(merge(A,B))
Out[130]: True

In [131]: %%timeit                                 
C = []
i = j = 0
while i < len(A) and j < len(B):
    if A[i] < B[j]:
        C.append(A[i])
        i += 1
    else:
        C.append(B[j])
        j += 1
C += A[i:] + B[j:]
   .....: 
1 loops, best of 3: 919 ms per loop


这个算法的顺序是什么?
推荐阅读
贾志军
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有