项目背景
在实际开发中,我们经常会遇到这样一种排序需求:
file1.txt file2.txt file10.txt file20.txt
如果使用普通的字符串字典序排序,结果会变成:
file1.txt file10.txt file2.txt file20.txt
这是因为字符串比较是逐字符比较的:
- "1" < "2"
- 但 "10" < "2"(因为比较的是字符 '1' 和 '2')
这显然不符合人类直觉。
人类的排序逻辑是:
当遇到连续数字时,应按数值大小比较,而不是逐字符比较。
这种排序方式被称为:
Natural Sort(自然排序)
它广泛应用于:
- 文件管理系统排序
- Windows 文件名排序
- Linux GUI 文件排序
- 图像序列排序(img1, img2, img10)
- 版本号排序
- 日志编号排序
在操作系统层面:
- Windows 使用自然排序
- macOS Finder 使用自然排序
- Linux 多数桌面环境也使用自然排序
Go 标准库并未内置自然排序,因此我们需要自行实现。
项目需求
本项目目标:
功能需求
- 实现字符串数组自然排序
- 支持任意位置数字比较
- 支持多个数字段比较
- 支持前导零
- 支持大小写控制
- 可扩展为版本号排序
示例
输入:
[]string{ "file1", "file10", "file2", "file20", }
输出:
file1 file2 file10 file20
相关技术
1. 字典序排序(Lexicographical Order)
Go 中:
sort.Strings(arr)
底层是逐字符比较:
- 从左到右比较
- 遇到不同字符即决定大小
缺点:
- 数字会按字符比较
2. 自然排序核心思想
自然排序的关键:
将字符串拆分为'数字段'和'非数字段'进行比较
例如:
file20.txt
拆分为:
["file", 20, ".txt"]
比较规则:
- 同为数字段 → 数值比较
- 同为字符串段 → 字典序比较
- 数字段优先于字符串段(可自定义)
3. Go 排序接口
Go 排序核心接口:
sort.Interface
需要实现:
- Len()
- Less(i, j int)
- Swap(i, j int)
我们只需实现 Less() 中的自然比较逻辑。
4. 算法时间复杂度
- 拆分复杂度:O(k)

