PB String Array(), Hosted Dynamic Number Arrays()

Started by Theo Gottwald, November 26, 2023, 06:24:28 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Theo Gottwald

Hosted dynamic number arrays are essentially strings, avoiding memory issues. 🧠 They function like PowerBASIC number arrays, as they are indeed the same. 🔄

To define an array, use:
`ReDim a(1 To items) At StrPtr(Container)`

Instead of a typical array variable, access elements with `HostArray(index)`. Sorting is performed using PowerBASIC's sort algorithm, and yes, binary search is included! 🔍

Provided is a single example, the Quad array, aptly named "SQud.inc". 📁 Utilize the "MultiplyQuadFile.bas" utility to generate all other number arrays from the Quad array. Simply compile and select "SQud.inc" to create additional types. 🛠�

For handling large arrays, remember to account for the string overhead and manage operations in substantial chunks. These arrays can store millions, but resizing one item at a time with `ReDim()` will be inefficient due to the string overhead. 🚀

Included is a utility data structure that could be quite useful:
- Quad array INC
- An application that constructs other array types
- Sample array procedures
- An example of hosting in a PowerBASIC String array

#Programming #PowerBASIC #DataStructures #Coding #TechTips #Arrays #SoftwareDevelopment #Optimization 🖥�💾🔢🛠�📊👨�💻🚀


'SQud.inc
'Public domain, use at own risk. SDurham
'Include or copy and paste.

    'Simple in-string dynamic Quad array.
    'Targeted use: dynamic number arrays hosted in PB String arry.
    'Since they're just strings memory issues don't arise.

    'This is basically just a PB array using, ReDim a(1 To items) At StrPtr(Container).
    'UBound() is the length of the host string divided the data size.

    'There is no data structure, jut a string.
    'Doesn't need to be freed.
    'To empty, Container = "".

    'For large arrays, ReDim() in large chunks to overcome string overhead.
    'Delete in chunks before ReDim().

    'add 100,000 random values to empty array = 0.000 seconds
    'sort array of 100,000 random value = 0.014 seconds
    'binary search array for 100,000 random values = 0.032 seconds

    'add 1,000,000 random values to empty array = 0.031 seconds
    'sort array of 1,000,000 random value = 0.157 seconds
    'binary search array for 1,000,000 random values = 0.317 seconds

#If Not %Def(%SQud230920)
    %SQud230920 = 1
    'In-string simple dynamic Quad array.
    %SQudSize = 8
    '----------------------------------------------
    Function SQudCount(ByRef Container As String) As Long
        'get item count
        Function = Len(Container) / %SQudSize
    End Function
    '----------------------------------------------
    Sub SQudReDim(ByRef Container As String, ByVal items As Long)
        'redimension array : data preserved
        Local current As Long
        current = SQudCount(Container)
        If items < 1 Then
            Container = ""
        ElseIf items < current Then
            Container = Left$(Container, items * %SQudSize)
        ElseIf items > current Then
            Container += Nul$((items - current) * %SQudSize)
        End If
    End Sub
    '----------------------------------------------
    Sub SQudInc(ByRef Container As String)
        'increase dimension by 1
        Local current As Long
        current = SQudCount(Container)
        SQudReDim(Container, current + 1)
    End Sub
    '----------------------------------------------
    Sub SQudDec(ByRef Container As String)
        'decrease dimension by 1
        Local current As Long
        current = SQudCount(Container)
        If current > 0 Then SQudReDim(Container, current - 1)
    End Sub
    '----------------------------------------------
    Sub SQudSet(ByRef Container As String, ByVal index As Long, ByVal value As Quad)
        'set value at one-based index
        Local a() As Quad
        Local items As Long
        items = SQudCount(Container)
        If index > 0 And index <= items Then
            ReDim a(1 To items) At StrPtr(Container)
            a(index) = value
        End If
    End Sub
    '----------------------------------------------
    Function SQudGet(ByRef Container As String, ByVal index As Long) As Quad
        'get value at one-based index
        Local a() As Quad
        Local items As Long
        items = SQudCount(Container)
        If index > 0 And index <= items Then
            ReDim a(1 To items) At StrPtr(Container)
            Function = a(index)
        End If
    End Function
    '----------------------------------------------
    Sub SQudInsert(ByRef Container As String, ByVal index As Long, ByVal value As Quad)
        'insert value at one-based index
        Local a() As Quad
        Local items As Long
        items = SQudCount(Container)
        If index > 0 And index <= items Then
            ReDim a(1 To items) At StrPtr(Container)
            Array Insert a(index), value
        End If
    End Sub
    '----------------------------------------------
    Sub SQudDelete(ByRef Container As String, ByVal index As Long)
        'delete value at one-based index
        Local a() As Quad
        Local items As Long
        items = SQudCount(Container)
        If index > 0 And index <= items Then
            ReDim a(1 To items) At StrPtr(Container)
            Array Delete a(index)
        End If
    End Sub
    '----------------------------------------------
    Sub SQudSort(ByRef Container As String)
        'non-recursive quick sort
        Local a() As Quad
        Local items As Long
        items = SQudCount(Container)
        If items > 1 Then
            ReDim a(1 To items) At StrPtr(Container)
            Array Sort a()
        End If
    End Sub
    '----------------------------------------------
    Function SQudSortSearch(ByRef Container As String, ByVal value As Quad) As Long
        'binary search for value : return index : zero if not found : array must be sorted
        Register i As Long
        Local bot, top As Long
        Local a() As Quad
        Local items As Long
        items = SQudCount(Container)
        If items Then
            ReDim a(1 To items) At StrPtr(Container)
            bot = 1 : top = items
            While top >= bot
                i = bot + top : Shift Right i, 1
                If value > a(i) Then
                    bot = i + 1
                ElseIf value < a(i) Then
                    top = i - 1
                Else
                    Function = i : Exit Function
                End If
            Wend
        End If
    End Function
    '----------------------------------------------
    Function SQudSortPoaition(ByRef Container As String, ByVal value As Quad) As Long
        'get sort insert position : array must be sorted or empty
        'if return = zero then add to end of array
        'else, SQudInsert() at returned index
        Register i As Long
        Local bot, top, compare As Long
        Local a() As Quad
        Local items As Long
        items = SQudCount(Container)
        If items Then
            bot = 1 : top = items
            While top >= bot
                ReDim a(1 To items) At StrPtr(Container)
                i = bot + top : Shift Right i, 1
                compare = Switch&(value > a(i), 1, value < a(i), -1) 'else match
                If compare > 0 Then
                    bot = i + 1
                ElseIf compare < 0 Then
                    top = i - 1
                Else
                    Function = i : Exit Function
                End If
            Wend
            If compare < 0 Then
                Function = i
            ElseIf i < items Then
                 Function = i + 1
            Else
               Function = 0
            End If
        Else
            Function = 0
        End If
    End Function
    '----------------------------------------------
    Sub SQudReverse(ByRef Container As String)
        'reverse array
        Register i As Long
        Register j As Long
        Local a() As Quad
        Local items As Long
        items = SQudCount(Container)
        If items > 1 Then
            ReDim a(1 To items) At StrPtr(Container)
            i = 1 : j = items
            While i < j
                Swap a(i), a(j)
                Incr i
                Decr j
            Wend
        End If
    End Sub
    '----------------------------------------------
    Sub SQudSplit(ByRef Container As String, delimited As String, delimiter As String)
        'split array on delimited string
        Register i As Long
        Local items As Long
        Local sa() As String
        Container = ""
        items = ParseCount(delimited, delimiter)
        SQudReDim(Container, items) : ReDim sa(1 To items)
        Parse delimited, sa(), delimiter
        For i = 1 To items
            SQudSet Container, i, Val(sa(i))
        Next i
    End Sub
    '----------------------------------------------
    Function SQudJoin(ByRef Container As String, delimiter As String) As String
        'join array to delimited string
        Register i As Long
        Local sa() As String
        Local items As Long
        items = SQudCount(Container)
        If items Then
            ReDim sa(1 To items)
            For i = 1 To items
                sa(i) = Format$(SQudGet(Container, i))
            Next i
            Function = Join$(sa(), delimiter)
        End If
    End Function
    '----------------------------------------------
#EndIf '%SQud230920�

Source: Powerbasic Forum