我正在用Python编写一个程序,该程序实现选择排序算法并以降序对列表的元素进行排序。
假设我的输入是l = [242, 18, 44, 201, 1111]
。
我的逻辑如下:
l = [242, 18, 44, 201, 1111] # switch l[0] (242) and l[len(l)-1] (1111)
l = [1111, 18, 44, 201, 242] # switch l[1] (18) and l[len(l)-1] (242)
l = [1111, 242, 44, 201, 18] # switch l[2] (44) and l[len(l)-2] (201)
输出为[1111, 242, 201, 44, 18]
。
因此,这是我根据上述逻辑实现的代码:
def selSort(l):
'''Sorts the list in descending order using a selection sort algorithm.
Params: l (list): unsorted list
Sorts: unsorted list in descending order
'''
start = len(l)-1
while start != 0:
for i in range(len(l)):
if l[i] < l[start]:
l[i], l[start] = l[start], l[i]
start -= 1
似乎我高估了我的逻辑,因为算法的输出为[1111, 18, 242, 201, 44]
。
经过一些调试之后,我发现在对遍历l
进行了几次遍历之后,while循环仍然没有达到终止条件。这意味着start
和i
之间会有一些不必要的重叠。例如,当start = 3
和i = 4
时,l[i] < l[start]
产生l = [1111, 242, 201, 18, 44]
。再次遍历之后,我们将得到上面显示的错误输出。
对于此问题,什么是优雅的解决方案(我知道选择排序不是最有效的算法)和Pythonic解决方案?我正在尝试不使用任何内置函数(len
和range
除外),方法或外部库(如果可能)来实现此目的。
我已经在此处签出了Selection Sort Algorithm Python和Selection Sort Algorithm in Java帖子。前者使用列表方法(我试图避免这种方法),而我对Java语法的理解不够充分,无法利用后者。
答案 0 :(得分:2)
这应该有效。它还使用range()来避免必须使用while循环。
from collections import Counter
import numpy as np
from scipy import linalg
lhs = (Counter({22.99: 1}), Counter({12.011: 2, 15.999: 2}), Counter({12.011: 7}))
rhs = Counter({12.011: 15, 15.999: 1})
# get unique keys that occur in any Counter in 2D
# each unique key represents a separate dimension
ks = np.array([*set().union(rhs, *lhs)])[:, None]
# get a helper function to convert Counters to vectors
ctr_to_vec = np.vectorize(Counter.__getitem__)
lhs_mat = ctr_to_vec(lhs, ks)
rhs_vec = ctr_to_vec(rhs, ks)
# compute coefficients solving the least-squares problem
coefs = linalg.lstsq(lhs_mat, rhs_vec)[0]
is_linear_comb = np.allclose(lhs_mat @ coefs, rhs_vec)
答案 1 :(得分:2)
选择排序算法(降序)的逻辑是:对表进行n-1次迭代(n是列表中元素的数量)。在第i次迭代中,我们选择索引i + 1和n之间的最高元素,然后将该元素与列表中位置i的元素交换。这将导致以下代码:
def selSort(l):
'''Sorts the list in descending order using a selection sort algorithm.
Params: l (list): unsorted list
Sorts: unsorted list in descending order
'''
for i in range(len(l)-1) :
posMax = i
for j in range(i+1,len(l)):
if l[j] > l[posMax]:
posMax = j
l[posMax], l[i] = l[i], l[posMax]
return l
l = selSort([242, 18, 44, 201, 1111])
print(l) #prints [1111, 242, 201, 44, 18]