我想编写一个基于customAl顺序对arr进行排序的代码,而不要使用sorted函数。
customAl = [dshbanfmg]
arr = [bba,abb,baa,mggfba,mffgh......]
伪代码:
def sortCA(arr, customAl):
dt = {}
generate dt order based on customAl
look up and sort arr
return result
newArr = [bba,baa,abb,mffgh,mggfba......]
我知道有一个类似的问题,但是答案被包装在我不想使用的排序函数中。有谁能比未排序的字典有更好的解决方案?
Sorting string values according to a custom alphabet in Python
答案 0 :(得分:1)
在我看来,编程是一种折衷,它取决于您最关心的部分。
具体来说,在这种情况下,您可以选择以str.index
来交换空间时间,或者可以使用额外的索引dict
来交换空间时间:
customAl = 'dshbanfmg'
arr = ['bba', 'abb', 'baa', 'mggfba', 'mffgh']
# trade time for space
# no extra space but, but O(n) to index
def sortCA1(arr, customAl):
return sorted(arr, key=lambda x: [customAl.index(c) for c in x])
# trade space for time
# extra space O(n), but O(1) to index
def sortCA2(arr, customAl):
dt = {c: i for i, c in enumerate(customAl)}
return sorted(arr, key=lambda x: [dt[c] for c in x])
# output: ['bba', 'baa', 'abb', 'mffgh', 'mggfba']
这是一个不使用sorted
功能的版本,我们可以根据自定义字母顺序使用存储桶。将arr拆分为第一个字符,如果一个存储桶中有多个元素,则递归地将其拆分为第二个字符...一种基数排序:
值得一提的是,长度是不同的,因此我们应该添加一个存储桶以不记录任何索引str。
def sortCA3(arr, customAl):
dt = {c: i + 1 for i, c in enumerate(customAl)} # keep 0 for none bucket
def bucket_sort(arr, start):
new_arr = []
buckets = [[] for _ in range(len(customAl) + 1)]
for s in arr:
if start < len(s):
buckets[dt[s[start]]].append(s)
else:
buckets[0].append(s)
for bucket in buckets:
if len(bucket) == 1:
new_arr += bucket
elif len(bucket) > 1:
new_arr += bucket_sort(bucket, start+1)
return new_arr
return bucket_sort(arr, 0)
测试并输出
customAl = 'dshbanfmg'
arr = ['bba', 'bb', 'abb', 'baa', 'mggfba', 'mffgh'] # add `bb` for test
print(sortCA4(arr, customAl))