我有3个整数类型的一维数组,每个数组长度相同(介于5到2千万个值之间),我想通过第二个数组并行排序(即保持相对位置),然后第三个数组,然后是第一个数组。有没有人对vb.net中最有效的方法有任何想法?
如果有帮助,第一个数组只是初始位置的记录(一旦完成各种计算,三个数组将重新排序到此顺序)。我需要对它们进行排序以确定第二个和第三个数组的唯一组合的数量(组合由数组中的位置决定 - 在下面的示例中组合为(0-1-4),(1-1-) 6)等)。一旦确定,我将根据第一个阵列取回它们。
我查看了array.sort,但只包含了2个并行数组。我有点担心将值放在元组(或任何其他格式)中,因为它(我假设 - 可能不是)在处理之前转换5到2千万条记录时会有很大的开销。
例如:
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中可用的选项感到困惑。
有没有人对解决这个问题的最佳方法有任何建议?
干杯,
答案 0 :(得分:0)
我认为您可以获得Link Array的备份。然后使用记录阵列对链接阵列进行排序,然后您可以使用行号阵列对未排序的链接阵列进行排序。你能试试吗?
答案 1 :(得分:0)
你没有说你是否想要在时间或空间上有效率,但是这需要大约3秒钟才能将2000万条记录从数组传输到列表,然后大约30秒来对它们进行排序,使用更少超过1GB的RAM。在我的电脑上。
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