2

我有 3 个整数类型的一维数组,每个数组的长度相同(在 5 到 2000 万个值之间),我想通过第二个数组对它们进行并行排序(即保持相对位置),然后是第三个数组,然后是第一个数组。有人对在 vb.net 中执行此操作的最有效方法有任何想法吗?

如果有帮助,第一个数组只是初始位置的记录(一旦完成各种计算,三个数组将重新排序到此顺序)。我需要对它们进行排序以确定第二个和第三个数组的唯一组合的数量(组合由数组中的位置确定 - 在下面的示例中,组合是 (0-1-4), (1-1- 6)等)。一旦确定,我将根据第一个数组将它们返回。

我查看了 array.sort ,但只涵盖了 2 个并行数组。我对将值放在元组(或任何其他格式)中有点谨慎,因为在处理之前转换 5 到 2000 万条记录时(我假设 - 也许不是)会是一个很大的开销。

例如:

Record Number Array: {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}

Link Array: {1, 1, 2, 1, 1, 2, 2, 2, 1, 2}

Line Number Array: {4, 6, 3, 5, 6, 7, 3, 2, 3, 4}

按第二个、第三个、第一个数组排序/排序后,预期输出将是:

Record Number (1st Array): {8, 0, 3, 1, 4, 7, 2, 6, 9, 5}

Link Array (2nd Array): {1, 1, 1, 1, 1, 2, 2, 2, 2, 2}

Line Number Array (3rd Array): {3, 4, 5, 6, 6, 2, 3, 3, 4, 7}

Array.sort 只允许您并行排序 2 个数组,我对 LinQ 中可用的选项有点困惑。

有人对解决此问题的最佳方法有任何建议吗?

干杯,

4

2 回答 2

0

我认为您可以获得链接阵列的备份。然后用 Record Array 对 Link Array 进行排序,然后可以用 Line Number Array 对未排序的 Link Array 进行排序。你能试试吗?

于 2013-08-13T14:38:19.760 回答
0

您没有说您是否希望在时间或空间方面高效,但是将 2000 万条记录从数组传输到列表大约需要 3 秒,然后对它们进行排序大约需要 30 秒,使用不到 1GB内存。在我的电脑上。

Option Infer On
Module Module1

Class Grouped
    Property RecNo As Integer
    Property Link As Integer
    Property LineNo As Integer

    Public Overrides Function ToString() As String
        Return String.Format("({0}, {1}, {2})", Me.RecNo, Me.Link, Me.LineNo)
    End Function

End Class
Sub Main()
    ' First try with the test data to show the correct result is obtained
    Dim recNos = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
    Dim links = {1, 1, 2, 1, 1, 2, 2, 2, 1, 2}
    Dim lineNos = {4, 6, 3, 5, 6, 7, 3, 2, 3, 4}

    ' transfer the arrays to a List
    Dim xs As New List(Of Grouped)
    xs.Capacity = recNos.Length

    For i = 0 To recNos.Length() - 1
        xs.Add(New Grouped With {.RecNo = recNos(i), .Link = links(i), .LineNo = lineNos(i)})
    Next

    ' sort the data
    Dim ys = xs.OrderBy(Function(x) x.Link).ThenBy(Function(x) x.LineNo).ToList()

    Console.WriteLine(String.Join(", ", ys))

    ' Now try with twenty million records
    Dim rand = New Random()
    Dim nRecs As Integer = 20000000
    recNos = Enumerable.Range(0, nRecs - 1).ToArray()
    ReDim links(nRecs - 1)
    ReDim lineNos(nRecs - 1)

    For i = 0 To nRecs - 1
        links(i) = rand.Next(0, 9)
        lineNos(i) = rand.Next(1, 9)
    Next

    Dim sw As New Stopwatch
    sw.Start()

    xs.Clear()
    xs.Capacity = nRecs

    For i = 0 To recNos.Length() - 1
        xs.Add(New Grouped With {.RecNo = recNos(i), .Link = links(i), .LineNo = lineNos(i)})
    Next

    sw.Stop()
    Console.WriteLine(sw.ElapsedMilliseconds.ToString())
    sw.Restart()

    ys = xs.OrderBy(Function(x) x.Link).ThenBy(Function(x) x.LineNo).ToList()

    sw.Stop()
    Console.WriteLine(sw.ElapsedMilliseconds.ToString())

    Console.ReadLine()

End Sub

End Module
于 2013-08-13T15:46:39.200 回答