【问题标题】:Sorting of list contained strings having alphabetic/numeric对包含具有字母/数字的字符串的列表进行排序
【发布时间】:2012-08-07 10:20:14
【问题描述】:

我想制作包含按字母顺序排列的字符串的排序列表,仅包含字母和数字以及数字的混合。我的客户要求这样排序:

排序在tablelist类型对象中包含Item Code: 111,111A,222,411G,300,411Z,G411,AG500,A111,AZ600,ABQ,ZZZ,AAN等

要求的结果:首先显示数字(例如 111 然后 222 然后 300 等...)接下来是带字母的数字(例如 111A 然后 411G 然后 411Z 等...)下一个带数字的字母(例如 A111 然后 G411 然后 AG500然后是 AZ600 等...)仅下一个字母(例如 AAN 然后 ABQ 然后 ZZZ 等...)

所以字符串可以是任何东西。但我想根据需要的结果进行排序。所以请帮我解决这个问题。

【问题讨论】:

  • 你有什么问题?你试过什么?

标签: c# sorting


【解决方案1】:
unsortedStringList.Sort(new AlphanumComparatorFastString());

AlphanumComparator:

    public class AlphanumComparatorFastString : IComparer<String>
    {
        public int Compare(string s1, string s2)
        {
            if (s1 == null)
                return 0;

            if (s2 == null)
                return 0;

            int len1 = s1.Length;
            int len2 = s2.Length;
            int marker1 = 0;
            int marker2 = 0;

            // Walk through two the strings with two markers.
            while (marker1 < len1 && marker2 < len2)
            {
                char ch1 = s1[marker1];
                char ch2 = s2[marker2];

                // Some buffers we can build up characters in for each chunk.
                char[] space1 = new char[len1];
                int loc1 = 0;
                char[] space2 = new char[len2];
                int loc2 = 0;

                // Walk through all following characters that are digits or
                // characters in BOTH strings starting at the appropriate marker.
                // Collect char arrays.
                do
                {
                    space1[loc1++] = ch1;
                    marker1++;

                    if (marker1 < len1)
                    {
                        ch1 = s1[marker1];
                    }
                    else
                    {
                        break;
                    }
                } while (char.IsDigit(ch1) == char.IsDigit(space1[0]));

                do
                {
                    space2[loc2++] = ch2;
                    marker2++;

                    if (marker2 < len2)
                    {
                        ch2 = s2[marker2];
                    }
                    else
                    {
                        break;
                    }
                } while (char.IsDigit(ch2) == char.IsDigit(space2[0]));

                // If we have collected numbers, compare them numerically.
                // Otherwise, if we have strings, compare them alphabetically.
                string str1 = new string(space1);
                string str2 = new string(space2);

                int result;

                if (char.IsDigit(space1[0]) && char.IsDigit(space2[0]))
                {
                    int thisNumericChunk = int.Parse(str1);
                    int thatNumericChunk = int.Parse(str2);
                    result = thisNumericChunk.CompareTo(thatNumericChunk);
                }
                else
                {
                    result = str1.CompareTo(str2);
                }

                if (result != 0)
                {
                    return result;
                }
            }
            return len1 - len2;
        }
    }

http://www.dotnetperls.com/alphanumeric-sorting上找到

【讨论】:

    【解决方案2】:

    试试这个:

    var text = "111,111A,222,411G,300,411Z,G411,AG500,A111,AZ600,ABQ,ZZZ,AAN";
    var list = text.Split(',').ToList();
    var result = list.OrderBy(i => i, new StringCompare());
    foreach (var item in result)
    {
        Console.WriteLine(item);
    }
    

    StringCompare 类:

    class StringCompare : IComparer<string>
    {
        string[] exps = new[] { @"^\d+$", @"^\d+[a-zA-Z]+$", @"^[a-zA-Z]\d+$", @"^[a-zA-Z]+\d+$" };
        public int Compare(string x, string y)
        {
            for (int i = 0; i < exps.Length; i++)
            {
                var isNumberx = Regex.IsMatch(x, exps[i]);
                var isNumbery = Regex.IsMatch(y, exps[i]);
    
                if (isNumberx && isNumbery)
                    return string.Compare(x, y);
                else if (isNumberx)
                    return -1;
                else if (isNumbery)
                    return 1;
                //return string.Compare(x, y);
            }
            return string.Compare(x, y);
        }
    }
    

    你会得到:

    111
    222
    300
    111A
    411G
    411Z
    A111
    G411
    AG500
    AZ600
    AAN
    ABQ
    ZZZ
    

    【讨论】:

      猜你喜欢
      • 2021-02-22
      • 2022-11-23
      • 2016-10-28
      • 1970-01-01
      • 2021-08-12
      • 1970-01-01
      • 2019-03-28
      • 2021-02-21
      相关资源
      最近更新 更多