带字节数组的c#排序列表不起作用

时间:2014-02-20 13:30:17

标签: c# arrays sorting byte sha

我创建了一个这样的列表:

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

并用数百万的沙子填满它。 之后我想这样排序:

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

7 个答案:

答案 0 :(得分:3)

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

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());

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

基本上,你必须返回:

  • &LT;如果x <0,则为0 ÿ
  • 0 if x == y
  • &GT;如果x> 0则为0 ÿ

答案 1 :(得分:1)

您得到异常是因为您尝试使用字节数组对列表进行排序。由于byte []没有实现IComparable,你无法做到这一点

答案 2 :(得分:1)

list.OrderBy(b => BitConverter.ToInt64(b, 0))

答案 3 :(得分:1)

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

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);
}

答案 4 :(得分:0)

您可以对byte[]进行排序,但是如何对List<Byte()>进行排序?哪个数组首先出现,哪个最后? ÿ

以下是使用List.Sort的重载的示例,该重载需要Comparison<T>。它比较所有字节的总和。

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

答案 5 :(得分:0)

Array.Sort()接受IComparer<T>接口实现或Comparison<T>委托。在任何一种情况下,如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;
}

答案 6 :(得分:0)

我偶然发现了这个问题,这个问题已经很老了,但与我现在试图做的非常接近,这就是为什么我想对此线程做出贡献。我正在尝试对List<Byte[]>进行排序,其值基本上是哈希值,这就是我想到的:

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

由于要使用散列,因此不应有null值,并且列表中的所有数组都应具有相同的长度。因此,比较功能可以简化如下:

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);
    }
}