How to order array in lexicographical order with m

2019-03-06 20:15发布

问题:

This is kinda complicated for me to understand

    Dim test() As Byte = New Byte() {50, 40, 30, 10, 10}
    Dim answer() As UInteger = SortLexicoGraphicallyArrayMappedFile(test)

The answer is the each Rotation sorted from lowest array value to highest array value.

Rotation 0 = 50, 40, 30, 10, 10
Rotation 1 = 10, 50, 40, 30, 10
Rotation 2 = 10, 10, 50, 40, 30
Rotation 3 = 30, 10, 10, 50, 40
Rotation 4 = 40, 30, 10, 10, 50

When I sort this array above by hand I should get

Rotation 2 = 10, 10, 50, 40, 30
Rotation 1 = 10, 50, 40, 30, 10
Rotation 3 = 30, 10, 10, 50, 40
Rotation 4 = 40, 30, 10, 10, 50
Rotation 0 = 50, 40, 30, 10, 10

So the answer should be 2, 1, 3, 4, 0

I get stuck in a infinite loop and I can't put my finger on it
My Previous question works because the data is always static here I try to move all the data around all over the place which is probably why it gets stuck I can't figure out a workaround around that.. i need to move all the data around to save cpu time later that's why I didn't pick the answer from the page below.

How to order array in lexicographical order vb.net

Here is my Code

Public Function GetRotation(Data As Byte(), rotation As UInteger) As Byte()
   'Rotation Left
    Dim rotationData As New List(Of Byte)

    Dim start As UInteger = Data.Length - rotation Mod Data.Length

    For i = 0 To Data.Length - 1
        rotationData.Add(Data((start + i) Mod (Data.Length)))
    Next

    Return rotationData.ToArray()
End Function

   Public Function SortLexicoGraphicallyArrayMappedFile(ByRef data As Byte()) As UInteger()
        Dim OrderedRotations As New List(Of UInteger)
        Dim rotatedData As Byte()
        Dim rotation As UInteger = 0


        Dim mmF As MemoryMappedFile
        mmF = MemoryMappedFile.CreateFromFile(My.Application.Info.DirectoryPath & "\outFile", FileMode.CreateNew, "test", CLng(data.LongLength * data.LongLength))
        Dim mmVA As MemoryMappedViewAccessor
        mmVA = mmF.CreateViewAccessor(0, data.LongLength * data.LongLength)

        Dim pos As Long = 0

        For rotation = 0 To data.Length - 1
            rotatedData = GetRotation(data, rotation)
            mmVA.WriteArray(Of Byte)(pos, rotatedData, 0, rotatedData.Length)
            pos += rotatedData.Length

        Next

        For rotation = 0 To data.Length - 1
            OrderedRotations.Add(rotation)
        Next

        Dim eachRotation As Integer = 0
        Dim data1() As Byte
        ReDim data1(data.Length - 1)
        Dim data2() As Byte
        ReDim data2(data.Length - 1)
        Dim index As Long
        For rotation = 0 To data.Length - 1
            Dim flag As Boolean
            Do
                flag = False
                For eachRotation = OrderedRotations.Count - 1 To 0 Step -1
                    mmVA.ReadArray(Of Byte)((OrderedRotations(rotation) * data.Length), data1, 0, data.Length)
                    If OrderedRotations(eachRotation) = OrderedRotations(rotation) Then Continue For
                    mmVA.ReadArray(Of Byte)((OrderedRotations(eachRotation) * data.Length), data2, 0, data.Length)

                    For index = 0 To data.Length - 1
                        If data1(index) > data2(index) Then
                            Exit For
                        ElseIf data1(index) < data2(index) Then
                            mmVA.WriteArray(Of Byte)((OrderedRotations(eachRotation) * data.Length), data1, 0, data1.Length)
                            mmVA.WriteArray(Of Byte)((OrderedRotations(rotation) * data.Length), data2, 0, data2.Length)

                            Dim tmpFirst As UInteger = OrderedRotations(rotation)
                            OrderedRotations(rotation) = OrderedRotations(eachRotation)
                            OrderedRotations(eachRotation) = tmpFirst
                            flag = True
                            Exit For
                        End If
                    Next
                Next
            Loop While flag
        Next

        Return OrderedRotations.ToArray()
    End Function

回答1:

I don't know if this is right but I fixed it for you.

Public Function SortLexicoGraphicallyArrayMappedFile(ByRef data As Byte()) As UInteger()
    Dim OrderedRotations As New List(Of UInteger)
    Dim rotatedData As Byte()
    Dim rotation As UInteger = 0


    Dim mmF As MemoryMappedFile
    mmF = MemoryMappedFile.CreateFromFile(My.Application.Info.DirectoryPath & "\outFile296", FileMode.CreateNew, "test", CLng(data.LongLength * data.LongLength))
    Dim mmVA As MemoryMappedViewAccessor
    mmVA = mmF.CreateViewAccessor(0, data.LongLength * data.LongLength)

    Dim pos As Long = 0

    For rotation = 0 To data.Length - 1
        rotatedData = GetRotation(data, rotation)
        mmVA.WriteArray(Of Byte)(pos, rotatedData, 0, rotatedData.Length)
        pos += rotatedData.Length

    Next

    For rotation = 0 To data.Length - 1
        OrderedRotations.Add(rotation)
    Next

    Dim eachRotation As Integer = 0
    Dim data1() As Byte
    ReDim data1(data.Length - 1)
    Dim data2() As Byte
    ReDim data2(data.Length - 1)
    Dim index As Long
    For rotation = 0 To data.Length - 1
        Dim flag As Boolean
        Do
            flag = False
            For eachRotation = OrderedRotations.Count - 1 To 0 Step -1
                If rotation = eachRotation Then Exit For
                mmVA.ReadArray(Of Byte)(rotation * data.Length, data1, 0, data.Length)
                mmVA.ReadArray(Of Byte)((eachRotation * data.Length), data2, 0, data.Length)

                For index = 0 To data.Length - 1
                    If data1(index) < data2(index) Then
                        Exit For
                    ElseIf data1(index) > data2(index) Then
                        mmVA.WriteArray(Of Byte)((eachRotation * data.Length), data1, 0, data1.Length)
                        mmVA.WriteArray(Of Byte)((rotation * data.Length), data2, 0, data2.Length)

                        Dim tmpFirst As UInteger = OrderedRotations(eachRotation)
                        OrderedRotations(eachRotation) = OrderedRotations(rotation)
                        OrderedRotations(rotation) = tmpFirst
                        flag = True
                        Exit For
                    End If
                Next
            Next
        Loop While flag
    Next

    Return OrderedRotations.ToArray()
End Function