我们知道python的sort方法是快速的O(nlgn)方法。
而且对于一个单词序列也是一样。
对于水果序列:
fruits=['peach','watermelon','pear','apple','grape','orange','banana','lemon']
排序后可以得到:
['apple', 'banana', 'grape', 'lemon', 'orange', 'peach', 'pear', 'watermelon']
可以看到是严格的字典序。(先比第一个字母,然后第二个。。。)
但是因为我们已经知道了桶排序这个东西,然后一个单词序列实际上ASCII序列,也就是一个256进制的整数。
所以我们只要准备256个桶便可以快速的用O(mn)来完成字典序。
其中m是平均单词长度。
代码如下:
def word_sort(words):
length=len(max(words,key=lambda w:len(w)))
bucket_sort_for_words(words,length)
def safe_word_index(w,d):
c=chr(0)
try:
c=w[d]
except:
c=chr(0)
finally:
return c
def bucket_sort_for_words(arr,d):
bucket=[[] for _ in range(256)]
d-=1
while d>=0:
for w in arr:
bucket[ord(safe_word_index(w,d))].append(w)
temp=[]
i=0
while i<256:
temp+=bucket[i]
bucket[i].clear()
i+=1
arr[:]=temp
d-=1
因为python的内置函数实在太过方便,我是能不用就不用,哈哈。
ps:python中不可以直接将其字符视为数字,要依靠chr函数对字符转换。
第一个函数是为了寻找最大长度,毕竟每个都要照顾到嘛。
第二个函数相当于一个安全的word【index】功能,如果不用这个函数,将产生数组越界错误;这函数发现越界时返回的是空字符串的ascii码。
第三个函数用256个桶来保存,收集也需要d次,每次收集完要清空一次桶(就跟吃过饭的碗要刷一刷一样,哈哈。)
最终arr被修改成字典序。
因为在两个字符串之间是按照元组比较法来比较,也就是说:
判断aa...aab(上百个a)>aa...aac(上百个a)可能会非常费时。
所以在sort函数中也许比较操作不是严格的常数操作。
那么这个时候我们的桶式排序也许是最好的选择。