写出更好的自然类型(比我的)

ang*_*son 8 .net unicode natural-sort codepoint

我在这里添加了对这个问题的答案:在C#中进行排序List<String>,它需要一个自然排序顺序,一个处理嵌入数字的顺序.

然而,我的实现是天真的,并且代替所有关于应用程序如何通过假设(土耳其测试任何人?)正确处理Unicode的帖子,我想我会请求帮助编写更好的实现.或者,如果有.NET的内置方法,请告诉我:)

我对该问题中答案的实现只是通过字符串,逐个字符地进行比较,直到遇到两个数字.然后它从两个字符串中提取连续的数字,这可能导致长度变化,用前导零填充最短的数字,然后进行比较.

但是,它存在问题.

例如,如果你在字符串x中有两个代码点,它们共同构成字符È,但在另一个字符串中你只有一个代码点,即那个字符.

我的算法会失败,因为它会将变音符号码视为单个字符,并将其与其他字符串中的È进行比较.

任何人都可以指导我如何妥善处理这个问题?我希望支持指定一个CultureInfo处理语言问题的对象,例如在德国比较"ss"和"ß",以及类似的东西.

我想我需要让我的代码枚举"真实字符"(我不知道真正的术语)而不是单个代码点.

什么是正确的方法?

此外,如果"自然"意味着"人类期望它的工作方式",我会在思考时添加以下内容:

  • 日期和时间怎么样?
  • 浮点值怎么样?
  • 还有其他被认为是"自然"的序列吗?
    • 这应该延伸多远?(Eeny,meeny,miny,moe)

Han*_*ant 7

这在Windows中已经可用,shell在资源管理器窗口中排列文件时使用自然排序顺序.它使用的比较功能被导出并可用于任何程序,至少从Windows 2000开始.虽然P/Invoke不是最好的解决方案,但它确实具有在过去10多年中经过数十亿次测试的相当大的优势.并以用户已经熟悉的方式对字符串进行排序.

处理变音符号已经是.NET的一部分了,string.Normalize()方法负责处理它.

这是一个使用它的示例程序,它根据原始线程中的请求正确排序字符串:

using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;

class Program {
    static void Main(string[] args) {
        string[] arr = new string[] { "1", "5", "3", "6", "11", "9", "NUM1", "NUM0" };
        Array.Sort(arr, new LogicalComparer());
        foreach (string s in arr) Console.WriteLine(s);
        Console.ReadLine();
    }
}
class LogicalComparer : IComparer<string> {
    public int Compare(string x, string y) {
        return StrCmpLogicalW(x.Normalize(), y.Normalize());
    }
    [DllImport("shlwapi.dll", CharSet = CharSet.Unicode, ExactSpelling = true)]
    private static extern int StrCmpLogicalW(string s1, string s2);
}
Run Code Online (Sandbox Code Playgroud)