如何对整数字符串进行排序?

11
我在对一个包含整数值的字符串列表进行排序时,遇到了一个奇怪的问题。然而,有些值可能会以一些字符为前缀。
例如:
// B1, 5, 50, A10, 7, 72, B3, A1, A2

基本上是页面数字,应该像这样排序:

// A1, A2, A10, B1, B3, 5, 7, 50, 72

但如果我使用默认字符串排序,那么它们将会像这样排序

// A1, A10, A2, B1, B3, 5, 50, 7, 72

有没有C#的解决方案?


你可以使用我整理并稍作修改的 NaturalStringComparer(不记得是从哪里获取了基础)。它使用了 Skizz 提到的 Win32 函数 StrCmpLogicalW。http://my.opera.com/Svishy/blog/2009/03/02/natural-sorting - Svish
6个回答

17

Alphanum将返回// 5、7、50、72、A1、A2、A10、B1、B3,而不是// A1 ... 5 - Carra
2
如果您查看一些代码示例,就会了解如何更改以适应略有不同的情况。 - John Feminella

5

这是我为我们的应用程序解决问题的方法,顺序将像在Windows目录中一样:

public class NaturalSortComparer : IComparer<string>
{
    public int Compare(string x, string y)
    {
        return StrCmpLogicalW(x, y);
    }

    [DllImport("shlwapi.dll", CharSet = CharSet.Unicode, ExactSpelling = true)]
    public static extern int StrCmpLogicalW(string x, string y);
}

使用方法:

  NaturalSortComparer comparer = new NaturalSortComparer();
  return comparer.Compare(string1, string2);

但这可能不完全符合您的要求:

// A1,A2,A10,B1,B3,5,7,50,72

这将给出:

// 5,7,50,72,A1,A2,A10,B1,B3


3
你需要的是自然排序。
Jeff Atwood曾在他的博客上发表过一篇很棒的文章,解释了这个概念,并链接到其他各种算法的来源,你可以将其作为示例。 人性化排序:自然排序

1
这是一个自定义比较器,可以按照您所需的顺序进行排序。请注意,此代码中没有错误/合理性检查:它假定所有字符串都处于正确的格式。
public class MyComparer : IComparer<string>
{
    public int Compare(string x, string y)
    {
        Match xMatch = Regex.Match(x, @"^(\D*)(\d+)$");
        Match yMatch = Regex.Match(y, @"^(\D*)(\d+)$");

        string xChars = xMatch.Groups[1].Value;
        string yChars = yMatch.Groups[1].Value;

        if ((xChars.Length == 0) && (yChars.Length > 0))
        {
            return 1;
        }
        else if ((xChars.Length > 0) && (yChars.Length == 0))
        {
            return -1;
        }
        else
        {
            int charsResult = xChars.CompareTo(yChars);

            return (charsResult != 0)
                ? charsResult
                : int.Parse(xMatch.Groups[2].Value)
                    .CompareTo(int.Parse(yMatch.Groups[2].Value));
        }
    }
}

您可以这样使用:

List<string> testList =
    new List<string>() { "B1","5","50","A10","7","72","B3","A1","A2" };

testList.Sort(new MyComparer());    // A1, A2, A10, B1, B3, 5, 7, 50, 72

0

不确定性能如何,但肯定可以进行优化,但它能够完成工作:

string[] sort(string[] data)
{
    return data
        .OrderBy(s => Regex.Match(s, @"^\D").Length == 0)
        .ThenBy(s => Regex.Match(s, @"\D*").Value)
       .ThenBy(s => Int32.Parse(Regex.Match(s, @"\d+").Value)).ToArray();
}

var result = sort(new string[] { "B1", "5", "50", "A10", "7", "72", "B3", "A1", "A2" });

0

嗯,你可以通过pInvoke Win32 API函数StrCmpLogicalW来实现你想要的功能(这就是资源管理器用于对文件名进行排序的方法)。唯一可能的缺点是排序不区分大小写。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接