【问题标题】:How to sort a List of integer arrays of varying size?如何对不同大小的整数数组列表进行排序?
【发布时间】:2015-02-14 17:05:54
【问题描述】:

我已经对此进行了广泛的搜索,所以如果这是重复的,请杀了我:D

我有一个字节数组列表 (List),其中数组的长度不同。我需要先按数组长度升序对列表进行排序,然后再按数组中的字节数对列表进行排序(请参见示例)。

例子:

我想从:

{0,1,2}
{0,4}
{0,3,2}
{0,1,3}
{0,2,4,6,1}
{0,1,1}
{0,3,4,5}

到:

{0,4}
{0,1,1}
{0,1,2}
{0,1,3}
{0,3,2}
{0,3,4,5}
{0,2,4,6,1}

它本质上是按字母顺序排列,但使用一组数字而不是字符(可以说是同一件事),有什么想法吗?

【问题讨论】:

  • 编写自定义比较器。

标签: c# arrays sorting


【解决方案1】:

您唯一需要做的就是实现一个IComparer<T> 接口并将其提供给排序算法。在这种情况下,算法如下所示:

public ByteArrayComparer : IComparer<byte[]> {

    public int Compare (byte[] ba, byte[] bb) {
        int n = ba.Length;  //fetch the length of the first array
        int ci = n.CompareTo(bb.Length); //compare to the second
        if(ci != 0) { //if not equal return the compare result
            return ci;
        } else { //else elementwise comparer
            for(int i = 0; i < n; i++) {
                if(ba[i] != bb[i]) { //if not equal element, return compare result
                    return ba[i].CompareTo(bb[i]);
                }
            }
            return 0; //if all equal, return 0
        }
    }

}

接下来可以使用List&lt;T&gt;.Sort方法:

List<byte[]> data = new List<byte[]>();
//add arrays to data
data.Sort(new ByteArrayComparer());
//data is now sorted

排序算法要求比较器是有效的,一个比较器满足一个排序关系的三个约束条件是有效的:

  1. 自反性:如果一个元素与其自身进行比较,则返回0
  2. 反对称:如果x小于y(返回小于0的东西),那么y大于x(大于0);
  3. 传递:如果x小于yy小于z,那么 x 小于 z

如果比较器不满足该关系,排序算法将无法正确排序,这仅仅是因为您的顺序没有意义。

【讨论】:

    【解决方案2】:

    为什么不简单地使用LINQ

    MyList = MyList.OrderBy(arr=>arr.Length).ThenBy(arr =>arr.Sum()).ToList();
    

    一个工作示例:

       List<int[]> a = new List<int[]>();
    
       int[] t1 = { 0, 4 };
       int[] t2 = { 0, 1, 2 };
       int[] t3 = { 0, 1, 3 };
       int[] t4 = { 0, 2, 4, 6, 1 };
       int[] t5 = { 0, 1, 1 };
       int[] t6 = { 0, 3, 4, 5 };
    
       a.Add(t1);
       a.Add(t2);
       a.Add(t3);
       a.Add(t4);
       a.Add(t5);
       a.Add(t6);
    
       a = a.OrderBy(arr=>arr.Length).ThenBy(arr =>arr.Sum()).ToList();
    
        foreach (int[] item in a)
        {
            foreach (int item2 in item)
            {
                 Console.Write(" "+item2);
          }
          Console.WriteLine();
       }
    

    样本输出:

    0 4
    0 1
    0 1 2
    0 1 3
    0 3 4 5
    0 2 4 6 1
    

    正如所指出的,这在 {3 4 5} 、 {4 5 3} 等场景中可能会失败

    【讨论】:

    • 我没有dv,但我认为它仍然不正确。我认为 OP 想要按字典顺序排序。所以 {1,200} 小于 {3,5} 因为第一个元素更小。如果不看第二个等等......
    • 什么是第一? {0,3,4,5} 或 {0,3,5,4} ?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-03-23
    • 1970-01-01
    • 1970-01-01
    • 2011-12-09
    • 2016-08-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多