如何修改现有数字基数排序代码实现指定字符串列表排序
适配思路
你现有的代码是数字基数排序的核心计数步骤,整体流程不需要推翻重构,只需要替换当前排序位的数值提取逻辑,就可以适配字符串排序需求,完全符合你不改动基数排序核心框架的要求。
逐处定位修改位置
原代码中有3处完全相同的位值计算逻辑(nums[i]//place)%10,这就是需要插入ord()转换的核心位置:
- 第一处:频率统计循环内
原代码行:
freq[(nums[i]//place)%10] += 1
这一步的目标是拿到「当前元素在本次处理位上的排序依据值」,数字场景下通过整除、取模提取10进制位值,字符串场景替换逻辑为:- 约定
place参数语义:和数字位处理逻辑对齐,从字符串最右侧的字符开始处理,即place=0对应字符串最后一个字符,place=1对应倒数第二个字符,以此类推 - 取出对应位置的字符后,通过
ord(字符) - ord('a')计算得到0-25的整数值,刚好对应a-z的字典序顺序 - 处理边界情况:如果当前字符串长度小于当前要取的位置索引,说明该位置无有效字符,给它赋一个比所有有效字符都小的默认值,保证短字符串排在长字符串前面
- 约定
- 第二、三处:逆序构建输出数组的循环内
这里的位值提取规则和频率统计环节完全一致,直接复用上面的转换逻辑替换原有计算式即可,保证统计和排序的规则统一。原代码两行:
output[freq[(nums[i]//place)%10] - 1] = nums[i] freq[(nums[i]//place)%10] -= 1
配套的小幅调整(不改动核心流程)
- 原
freq数组初始长度为10,对应数字0-9的取值范围,现在因为字符+边界空值的取值范围共27个(空值1个 + a-z共26个),只需要把freq的初始长度改为27即可,无需改动频率统计的累加逻辑 - 原
output数组初始化填充0,现在存储的是字符串,只需要把初始值改为空字符串,不影响后续赋值流程
参考实现片段
你可以把位值提取的逻辑单独抽成小函数,避免三处重复写代码:
def get_char_sort_value(s, place): # 空位置映射到freq的索引0 if len(s) <= place: return 0 # 取对应位置字符,计算a-z的偏移量,映射到freq的1-26索引 target_char = s[-(place + 1)] return ord(target_char) - ord('a') + 1
替换后原来三处位值计算全部调用这个函数,就可以实现字符串的计数排序。
你举例的最终效果,只需要两步就能落地:
- 先对列表里的每个字符串单独做字符级排序(也就是把每个字符串当成字符列表,跑改好的计数排序,得到内部字符有序的新字符串)
- 再对所有生成的新字符串列表,从最右侧字符开始逐位做稳定计数排序,就能得到你预期的
[aelpp ,ackst, eety, efloorvw]结果
内容的提问来源于stack exchange,提问作者user15393230
相关产品推荐
相关产品推荐

