基于自定义字母顺序python的排序数组

时间:2019-05-07 23:15:30

标签: python sorting

我想编写一个基于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

1 个答案:

答案 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))