Home > Blockchain >  how would i go about counting consecutive items that share the same value in an array? vb.net
how would i go about counting consecutive items that share the same value in an array? vb.net

Time:08-02

i'm trying to create a RLE compression & decompression tool, problem is that i don't know how to count each consecutive items in an array, that share the same value.

suppose a file with this byte string:

00 00 00 FF 99 88 88 77 22 00 00 00 00 00 00 00 00 00 00

how'd i receive something like 3 00 1 FF 1 99 2 88 1 77 1 22 10 00?

and how would i split the count like 255 0 5 0 instead of 260 0?

here is my compressRLE() function right now:

Public Sub compressRLE(org As String, cmp As String)
        Dim inputFile = IO.File.Open(org, IO.FileMode.Open)
        Dim bytes = New Byte(2147483647 - 1) {}
        Dim bytearray = bytes.ToArray()
        Dim nbytes As Array = {}

        While inputFile.Read(bytes, 0, 2147483647) > 0
            My.Computer.FileSystem.WriteAllBytes(2147483647, bytes, True)
        End While

        For i = 0 To bytearray.Length
            If bytearray(i) = bytearray(i   1) Then

            End If
        Next i

        inputFile.Close()
    End Sub

CodePudding user response:

You will need to do several things:

  1. Split the byte array string
  2. Loop over the items returned from the split
  3. Keep track of the current "consecutive" item
  4. If the currently looped item matches the current consecutive item, then increase it's total
  5. Otherwise, start a new total and set the new current consecutive item

Here is an example:

Private Function ConsecutiveItemCount(delimitter As String, input As String) As IEnumerable(Of KeyValuePair(Of String, Integer))
    If (String.IsNullOrEmpty(delimitter)) Then
        Throw New ArgumentNullException(NameOf(delimitter))
    End If
    If (String.IsNullOrWhiteSpace(input)) Then
        Throw New ArgumentNullException(NameOf(input))
    End If
    
    Dim everyItem = input.Split({ delimitter }, StringSplitOptions.RemoveEmptyEntries)        
    Dim consecutiveItems = New List(Of KeyValuePair(Of String, Integer))()
    For index As Integer = 0 To everyItem.Length - 1
        Dim currentlyIteratedItem = everyItem(index)
        If (consecutiveItems.Count = 0) Then
            consecutiveItems.Add(New KeyValuePair(Of String, Integer)(currentlyIteratedItem, 1))
            Continue For
        End If

        Dim currentlyIncrementingItem = consecutiveItems.Last()
        If (currentlyIncrementingItem.Key() = currentlyIteratedItem) Then
            Dim newConsecutiveTotal = currentlyIncrementingItem.Value   1
            consecutiveItems.Item(consecutiveItems.Count - 1) = New KeyValuePair(Of String, Integer)(currentlyIteratedItem, newConsecutiveTotal)
        Else
            consecutiveItems.Add(New KeyValuePair(Of String, Integer)(currentlyIteratedItem, 1))
        End If
    Next
    
    Return consecutiveItems
End Function

Live Demo: https://dotnetfiddle.net/BCSe3N

CodePudding user response:

Something like this,

Public Function DoCountsEx(byts() As Byte) As List(Of Counts)
    Dim cts As New List(Of Counts)
    If byts.Length > 0 Then
        Dim aCT As New Counts(byts(0), 0)
        Dim idx As Integer = 1
        Do While idx < byts.Length
            If byts(idx) = aCT.bytVal Then
                aCT.count  = 1
            Else
                cts.Add(aCT)
                aCT = New Counts(byts(idx), idx)
            End If
            idx  = 1
        Loop
        cts.Add(aCT)
    End If
    Return cts
End Function

Public Class Counts
    Public bytVal As Byte
    Public count As Integer
    Public bytLoc As Integer  'location start in buffer
    Public Sub New(val As Byte, loc As Integer)
        Me.bytVal = val
        Me.bytLoc = loc
        Me.count = 1
    End Sub
End Class

Test

    ' byts() = 00 00 00 FF 99 88 88 77 22 00 00 00 00 00 00 00 00 00 00
    Dim cts As List(Of Counts) = DoCountsEx(byts)
    'check
    Debug.WriteLine("")
    For Each c As Counts In cts
        Dim hex As String = Convert.ToString(c.bytVal, 16).PadLeft(2, "0"c)
        Debug.WriteLine("Value:{0}  Count:{1}  Location:{2}", hex, c.count, c.bytLoc)
    Next

Debug Output

Value:00  Count:3  Location:0
Value:ff  Count:1  Location:3
Value:99  Count:1  Location:4
Value:88  Count:2  Location:5
Value:77  Count:1  Location:7
Value:22  Count:1  Location:8
Value:00  Count:10  Location:9
  • Related