【问题标题】:c# sorting list with byte array doesn't workc# 使用字节数组排序列表不起作用
【发布时间】:2014-02-20 13:30:17
【问题描述】:

我创建一个这样的列表:

private List<byte[]> shaList = new List<byte[]>();

并用数百万个 shas 填充它。 之后我想这样排序:

shaList.Sort();

但它会抛出异常:

Unbehandelte Ausnahme: System.InvalidOperationException: Fehler beim Vergleichen
von zwei Elementen im Array. ---> System.ArgumentException: Mindestens ein 
Objekt muss IComparable implementieren.
bei System.Collections.Comparer.Compare(Object a, Object b)
bei System.Collections.Generic.ObjectComparer`1.Compare(T x, T y)
bei System.Collections.Generic.ArraySortHelper`1.SwapIfGreaterWithItems(T[] 
keys, IComparer`1 comparer, Int32 a, Int32 b)
bei System.Collections.Generic.ArraySortHelper`1.QuickSort(T[] keys, Int32 
left, Int32 right, IComparer`1 comparer)
bei System.Collections.Generic.ArraySortHelper`1.Sort(T[] keys, Int32 index,
Int32 length, IComparer`1 comparer)
--- Ende der internen Ausnahmestapelüberwachung ---
bei System.Collections.Generic.ArraySortHelper`1.Sort(T[] keys, Int32 index,
Int32 length, IComparer`1 comparer)
bei System.Array.Sort[T](T[] array, Int32 index, Int32 length, IComparer`1 
comparer)
bei System.Collections.Generic.List`1.Sort(Int32 index, Int32 count, I
Comparer`1 comparer)
bei System.Collections.Generic.List`1.Sort()

我不知道如何自行排序。我在学校里只有冒泡和插入排序,但是用冒泡排序对数百万个哈希进行排序...... xD

//3vilc00kie

【问题讨论】:

  • 您可以对byte[] 进行排序,但您希望如何对byte[] 的列表进行排序?哪个数组先出现,哪个最后出现?

标签: c# arrays sorting byte sha


【解决方案1】:

您可以实现自定义比较器:

class ByteArrayComparer : IComparer<byte[]> {
    public int Compare(byte[] x, byte[] y) {
        // implement your comparison criteria here
    }
}

然后像这样对您的列表进行排序:

List<byte[]> shaList = new List<byte[]>();
shaList.Sort(new ByteArrayComparer());

您的 Compare 函数应返回的内容在此处定义:http://msdn.microsoft.com/en-us/library/xh5ks3b3(v=vs.110).aspx

基本上,你必须返回:

  • 0 如果 x == y
  • > 如果 x > y 则为 0

【讨论】:

  • 好的,Compare函数的返回值是多少?如果 x 大于 y?像 C 中的 strcmp 一样?
【解决方案2】:

您收到异常是因为您尝试使用字节数组对列表进行排序。由于 byte[] 没有实现 IComparable 你不能这样做

【讨论】:

    【解决方案3】:
    list.OrderBy(b => BitConverter.ToInt64(b, 0))
    

    【讨论】:

      【解决方案4】:

      不清楚你想要什么,但也许是这样:

      shaList.Sort(System.Collections.StructuralComparisons.StructuralComparer.Compare);
      

      StructuralComparisons 是 .NET 版本 4.0 (2010) 中引入的 static class。它的属性StructuralComparer 给出了一个比较“按结构”的对象,这类似于数组(或元组)中每个条目之后的字典顺序。它通过Compare 的方法做到这一点;上面Compare通过方法组转换变成了委托。

      重要补充:这似乎仅在列表中的所有字节数组具有相同长度时才有效。

      测试代码:

      static void Main()
      {
          var shaList = new List<byte[]>
          {
              new byte[] { 20, 29, },
              new byte[] { 22, 29, },
              new byte[] { 2, 255, },
              new byte[] { 22, 0, },
          };
      
          shaList.Sort(System.Collections.StructuralComparisons.StructuralComparer.Compare);
      }
      

      【讨论】:

      • 所有 shas 肯定有相同的长度......我会试试这个,因为它是最简单的解决方案。希望它不缺乏性能
      • @RaphiPour 对我来说仍然不清楚你想要什么。排序SHAs 是否有意义,我不确定?我希望这会表现得非常好。 List&lt;&gt;.Sort 进行快速就地排序(精确算法略微依赖于 .NET 版本),在大多数情况下,我认为 StructuralComparer 只需要查看它所比较的​​两个数组中的第 0 个条目即可.
      【解决方案5】:

      您可以对byte[] 进行排序,但您希望如何对List&lt;Byte()&gt; 进行排序?哪个数组先出现,哪个最后出现?是的

      这是一个使用 List.Sort 重载的示例,它采用 Comparison&lt;T&gt;。它比较所有字节的总和。

      shaList.Sort((b1, b2) => b1.Sum(b => b).CompareTo(b2.Sum(b => b)));
      

      【讨论】:

        【解决方案6】:

        Array.Sort() 接受 IComparer&lt;T&gt; 接口实现或 Comparison&lt;T&gt; 委托。在任何一种情况下,如Paolo Tedesco 所述,您必须编写一个接受两个字节数组并返回数值比较结果的函数。

        这是一个简洁的实现,可以有效地做到这一点:

        int CompareByteArrays(byte[] a, byte[] b)
        {
            var length = Math.Min(a.Length, b.Length);
            for (var i = 0; i < length; i++)
            {
                var diff = a[i] - b[i];
                if (diff != 0)
                    return diff;
            }
            return a.Length - b.Length;
        }
        

        【讨论】:

          【解决方案7】:

          我偶然发现了这个很老的问题,但与我现在尝试做的非常接近,这就是我想为这个线程做出贡献的原因。我正在尝试对List&lt;Byte[]&gt; 进行排序,其值基本上是哈希值,这就是我想出的:

          [SuppressUnmanagedCodeSecurity]
          internal static class NativeMethods
          {
              [DllImport("MSVCRT.dll", CallingConvention=CallingConvention.Cdecl, ExactSpelling=true)]
              private static extern Int32 memcmp([In] IntPtr pointer1, [In] IntPtr pointer2, [In] UIntPtr count);
          
              internal static Int32 CompareSequences(Byte[] array1, Byte[] array2)
              {
                  if (ReferenceEquals(array1, array2))
                      return 0;
          
                  if (array1 == null)
                      return 1;
          
                  if (array2 == null)
                      return -1;
          
                  if (array1.Length != array2.Length)
                      return -Math.Min(Math.Max(array1.Length - array2.Length, -1), 1);
          
                  unsafe
                  {
                      fixed (Byte* pointer1 = array1, pointer2 = array2)
                          return -Math.Min(Math.Max(memcmp((IntPtr)pointer1, (IntPtr)pointer2, (UIntPtr)array1.Length), -1), 1);
                  }
              }
          }
          

          用法:

          List<Byte[]> hashes = ComputeHashes();
          hashes.Sort(NativeMethods.CompareSequences);
          

          这就是它的作用:

          1. Null 数组位于列表底部。
          2. 非空数组按长度排序,然后按“内容”排序:
            • 如果存在长度不匹配的情况,则以更大的数组为准。
            • 在存在相同长度的情况下,以第一个不匹配字节较大的数组为准。

          由于您使用的是哈希,因此不应有空值,并且列表中的所有数组都应该具有相同的长度。因此,比较函数可以简化为:

          internal static Int32 CompareSequences(Byte[] array1, Byte[] array2)
          {
              unsafe
              {
                  fixed (Byte* pointer1 = array1, pointer2 = array2)
                      return -Math.Min(Math.Max(memcmp((IntPtr)pointer1, (IntPtr)pointer2, (UIntPtr)array1.Length), -1), 1);
              }
          }
          

          【讨论】:

            猜你喜欢
            • 2015-01-02
            • 2016-11-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2019-03-12
            • 2016-12-04
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多