这是我在这里的第一个问题,因此我接受任何/所有提示,以防我的问题措辞不正确。
首先,问题是
说我们有以下数组A = [(1,'cat'),(1,'dog'),(0,'giraffe'),(0,'cheetah'),(1,'elephant' )]
我需要使用一种算法,该算法将根据每个组件的第一个元素(即数字)对该列表进行排序。需要特别指出的是,它不必是一种稳定的算法(我想这意味着我们不必考虑数字后面的单词的排序,只需将0放在所有1之前)
我还应该提到,我不希望采用创建边数组的策略,当算法对它们进行排序时,将在结果中填充这些边数组。要求算法对同一数组内的数组进行排序。
我设计的代码如下:
def SwapAround(A, start, end):
start_pos = start
for i in range(start,end):
if A[i] < A[end]:
A[i], A[start_pos] = A[start_pos], A[i]
start_pos = start_pos + 1
A[start_pos], A[end] = A[end], A[start_pos]
return start_pos
A=[(1,'cat'),(0,'dog'),(1,'kangaroo'),(0,'mule'),(1,'giraffe'),(1,'dog'),
(0,'bat')]
SwapAround(A,0,len(A) - 1)
print(A)
尽管我非常有信心它应该起作用(至少逐行浏览代码对我来说是很有意义的),但是我对此有一些特殊的问题。
代码对列表进行排序,但不完全...例如,我最近的输出是:
[(0, 'bat'), (0, 'dog'), (1, 'kangaroo'), (0, 'mule'), (1, 'giraffe'), (1, 'dog'), (1, 'cat')]
列表较小时,它实际上是有效的,今天早上我醒来却傻眼了,将另外两个组件添加到列表中,但它不起作用。
您能否告诉我是否可以看到我应该立即考虑的“错误”内容以及其背后的理由,以便我可以完全理解。
第二个问题:如果我想向列表中添加数字也为2的组件(这意味着我的算法必须在0,1,2之间进行排序,而不仅仅是0和1),那么您是否会使用完全不同的算法还是应该继续工作?我最初的想法是交换将无法正常工作(并且不适用于此算法),也许CountingSort或RadixSort会更好,所以您的输入将倍受赞赏。
答案 0 :(得分:3)
您的算法在概念上是错误的,尽管它已经接近解决方案了。
算法的重要问题是,只有第一个要交换的元素会改变。相反,您需要同时移动最后一个元素和第一个元素的索引。
def sort_binary_key(arr):
l, u = 0, len(arr) - 1
while l < u:
if arr[l] == 1 and arr[u] == 0:
arr[l], arr[u] = arr[u], arr[l]
elif arr[l] == 1:
u -= 1
elif arr[u] == 0:
l += 1
else:
u -= 1
l += 1
对于问题的第二部分:
是的,有可能。运行两次以上算法。在第一次运行中,将所有带有0的元素移到数组的下部,将所有其他元素移到数组的上部。然后在数组的第二部分上运行相同的算法,在以1和2作为第一元组成员的元素之间进行排序。
def sort_binary_key(arr, l, u, key_mapper):
while l < u:
al, au = key_mapper(arr[l]), key_mapper(arr[u])
if al == 1 and au == 0:
arr[l], arr[u] = arr[u], arr[l]
elif al == 1:
u -= 1
elif au == 0:
l += 1
else:
u -= 1
l += 1
return l
def sort_ternary(arr):
tmp = sort_binary_key(arr, 0, len(arr) - 1, lambda t: 0 if t == 0 else 1)
sort_binary_key(arr, tmp, len(arr) - 1, lambda t: 0 if t == 1 else 1)
请注意,以上代码仅用于演示。此代码适用于整数列表,而不是OP提供的输入。
答案 1 :(得分:0)
您的算法无法在更深层次上起作用。 您正在运行 O(n)复杂度常规排序算法。没有平均复杂度的一般排序算法(如果找到一种,请告诉我!)。检查this table of complexities的不同排序算法。
如果您的场景仅包含0
和1
,并且您希望所有0
都在开头,1
都在结尾(不稳定),则可以用O(n)完成
(请检查Paul's Answer来了解如何),并且您的算法完全不同。
您可以使用python列表sort
并只需传递密钥:
A = [(1,'cat'), (1,'dog'), (0,'giraffe'), (0,'cheetah'),(1,'elephant')]
sorted(A, key=lambda x: x[0])
>>> [(0, 'giraffe'), (0, 'cheetah'), (1, 'cat'), (1, 'dog'), (1, 'elephant')]
您也可以考虑使用辅助键(名字和数字):
B = [(1,'cat'), (0,'cat'), (0,'giraffe'), (0,'cheetah'),(1,'elephant')]
sorted(B, key=lambda x: (x[1], x[0]))
>>> [(0, 'cat'), (1, 'cat'), (0, 'cheetah'), (1, 'elephant'), (0, 'giraffe')]
Python有一个default sorting,在您的情况下,您可以简单地编写:
C = [(1,'cat'), (0,'cat'), (0,'giraffe'), (0,'cheetah'),(1,'elephant')]
sorted(C)
>>> [(0, 'cat'), (1, 'cat'), (0, 'cheetah'), (1, 'elephant'), (0, 'giraffe')]