Sort string in place (Structure Static Array) exemple

Share your advanced PureBasic knowledge/code with the community.
User avatar
Guimauve
Enthusiast
Enthusiast
Posts: 742
Joined: Wed Oct 22, 2003 2:51 am
Location: Canada

Sort string in place (Structure Static Array) exemple

Post by Guimauve »

Hello everyone.

I have worked around today this is the result. It's just an exemple and I'm sure better job can be done.

Regards

Guimauve

Code: Select all

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; AUTOMATICALLY GENERATED CODE, DO NOT MODIFY
; UNLESS YOU REALLY, REALLY, REALLY MEAN IT !!
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; Code generated by : Dev-Type
; Project name : Sort string in place exemple
; File name : StringSort in place.pb
; File Version : 1.0.0
; Programmation : Experimental code
; Programmed by : Guimauve
; Creation Date : 05-11-2006
; Last update : 05-11-2006
; Coded for PureBasic V4.00
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; Notes : Heros
;
; This code it's just a test for sorting string in
; place inside a Structure static array. 
;
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<<<<<<<<<<<<<< !!! WARNING !!! <<<<<<<<<<<<<<<<<
;
; THE SORTING TECHNICS IS BASED ON BUBBLE SORT.
; IT'S GOOD FOR SMALL ARRAY [n] < 50. MORE REASERCH
; IS NEEDED FOR BETTER PERFORMANCE ON LARGE STATIC 
; ARRAY.
;
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Size Array Constants <<<<<

#HEROS_NAME_MAX = 15

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Structure declaration <<<<<

Structure Heros
  
  Name.s[#HEROS_NAME_MAX]
  
EndStructure

; <<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< The mutators <<<<<

Macro SetHerosName(HeroA, Index, Name_String)
  
  HeroA\Name[Index] = Name_String
  
EndMacro

; <<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< The observators <<<<<

Macro GetHerosName(HeroA, Index)
  
  HeroA\Name[Index]
  
EndMacro

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< StringSort Ascendant operator <<<<<

Procedure StringSortAscendantHerosName(*HeroA.Heros)
  
  StringSortSwapped.b = #True
  
  While StringSortSwapped = #True
    
    StringSortSwapped = #False
    
    For Index = #HEROS_NAME_MAX - 1 To 1 Step -1
      
      LenString01 = Len(GetHerosName(*HeroA, Index))
      LenString02 = Len(GetHerosName(*HeroA, Index - 1))
      
      If LenString01 > LenString02
        LenMin = LenString02
      ElseIf LenString01 < LenString02
        LenMin = LenString01
      Else
        LenMin = LenString01
      EndIf
      
      For CharIndex = 0 To LenMin
        
        AsciiString01 = Asc(UCase(Mid(GetHerosName(*HeroA, Index), CharIndex, 1)))
        AsciiString02 = Asc(UCase(Mid(GetHerosName(*HeroA, Index - 1), CharIndex, 1)))
        
        If AsciiString01 > AsciiString02
          SwapNeeded.b = -1
          Break
        ElseIf AsciiString01 < AsciiString02
          SwapNeeded = 1
          Break
        EndIf
        
      Next
      
      If SwapNeeded = 0
        If LenString01 < LenString02
          SwapNeeded = 1
        EndIf
      EndIf
      
      If SwapNeeded = 1
        Swap GetHerosName(*HeroA, Index), GetHerosName(*HeroA, Index - 1)
        StringSortSwapped = #True
        SwapNeeded = 0
      EndIf
      
    Next
    
  Wend
  
EndProcedure

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< StringSort Descendant operator <<<<<

Procedure StringSortDescendantHerosName(*HeroA.Heros)
  
  StringSortSwapped.b = #True
  
  While StringSortSwapped = #True
    
    StringSortSwapped = #False
    
    For Index = 0 To #HEROS_NAME_MAX - 2
      
      LenString01 = Len(GetHerosName(*HeroA, Index))
      LenString02 = Len(GetHerosName(*HeroA, Index + 1))
      
      If LenString01 > LenString02
        LenMin = LenString02
      ElseIf LenString01 < LenString02
        LenMin = LenString01
      Else
        LenMin = LenString01
      EndIf
      
      For CharIndex = 0 To LenMin
        
        AsciiString01 = Asc(UCase(Mid(GetHerosName(*HeroA, Index), CharIndex, 1)))
        AsciiString02 = Asc(UCase(Mid(GetHerosName(*HeroA, Index + 1), CharIndex, 1)))
        
        If AsciiString01 > AsciiString02
          SwapNeeded.b = -1
          Break
        ElseIf AsciiString01 < AsciiString02
          SwapNeeded = 1
          Break
        EndIf
        
      Next
      
      If SwapNeeded = 0
        If LenString01 < LenString02
          SwapNeeded = 1
        EndIf
      EndIf
      
      If SwapNeeded = 1
        Swap GetHerosName(*HeroA, Index), GetHerosName(*HeroA, Index + 1)
        StringSortSwapped = #True
        SwapNeeded = 0
      EndIf
      
    Next
    
  Wend
  
EndProcedure

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< The Copy operator : A = Source : B = Destination <<<<<

Macro CopyHeros(HeroA, HeroB)
  
  For Index = 0 To #HEROS_NAME_MAX - 1
    SetHerosName(HeroB, Index, GetHerosName(HeroA, Index))
  Next

EndMacro

; <<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Debugging macro <<<<<

Macro DebugHeros(HeroA)
  
  For Index = 0 To #HEROS_NAME_MAX - 1
    Debug GetHerosName(HeroA, Index)
  Next
  
EndMacro

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Code generated in : 00.047 seconds <<<<<
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< We fill Myheros structure with names. <<<<<

MyHeros.Heros

SetHerosName(MyHeros, 00, "Zoro")
SetHerosName(MyHeros, 01, "SuperMan")
SetHerosName(MyHeros, 02, "SpiderMan")
SetHerosName(MyHeros, 03, "Freak")
SetHerosName(MyHeros, 04, "Morpheus")
SetHerosName(MyHeros, 05, "Fred")
SetHerosName(MyHeros, 06, "Athena")
SetHerosName(MyHeros, 07, "Zeus")
SetHerosName(MyHeros, 08, "Hercule")
SetHerosName(MyHeros, 09, "Achille")
SetHerosName(MyHeros, 10, "Luke")
SetHerosName(MyHeros, 11, "Anakin")
SetHerosName(MyHeros, 12, "Mace Windu")
SetHerosName(MyHeros, 13, "Yoda")
SetHerosName(MyHeros, 14, "Obiwan")

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< We copy MyHeros to test the sort commands on the same duty. <<<<<

CopyHeros(MyHeros, MyHerosCopy00.Heros)
CopyHeros(MyHeros, MyHerosCopy01.Heros)

; <<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< We run the test <<<<<

Debug "MyHeros original list"
DebugHeros(MyHeros)
Debug ""

Debug "MyHeros Sorted Ascendant"
StringSortAscendantHerosName(MyHerosCopy00)
DebugHeros(MyHerosCopy00)
Debug ""

Debug "MyHeros Sorted Descendant"
StringSortDescendantHerosName(MyHerosCopy01)
DebugHeros(MyHerosCopy01)
Debug ""

; <<<<<<<<<<<<<<<<<<<<<<<
; <<<<< END OF FILE <<<<<
; <<<<<<<<<<<<<<<<<<<<<<<
User avatar
Guimauve
Enthusiast
Enthusiast
Posts: 742
Joined: Wed Oct 22, 2003 2:51 am
Location: Canada

Post by Guimauve »

A more optimized sort algorythm.

[EDIT] More simple string compare

Regards
Guimauve

Code: Select all

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; AUTOMATICALLY GENERATED CODE, DO NOT MODIFY
; UNLESS YOU REALLY, REALLY, REALLY MEAN IT !!
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Size Array Constants <<<<<

#HEROS_NAME_MAX = 15

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Structure declaration <<<<<

Structure Heros
  
  Name.s[#HEROS_NAME_MAX]
  
EndStructure

; <<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< The mutators <<<<<

Macro SetHerosName(HeroA, Index, Name_String)
  
  HeroA\Name[Index] = Name_String
  
EndMacro

; <<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< The observators <<<<<

Macro GetHerosName(HeroA, Index)
  
  HeroA\Name[Index]
  
EndMacro

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< StringSort Ascendant operator <<<<<

Procedure StringSortAscendantHerosName(*HeroA.Heros)
  
  ShellSortGap.l = #HEROS_NAME_MAX - 1
  
  Repeat
    
    ShellSortGap >> 1
    
    Repeat
      
      ShellSortSwapped.b = #False
      
      For Index = 0 To (#HEROS_NAME_MAX - 1 - ShellSortGap)
        
        If UCase(GetHerosName(*HeroA, Index)) > UCase(GetHerosName(*HeroA, Index + ShellSortGap))
          Swap GetHerosName(*HeroA, Index), GetHerosName(*HeroA, Index + ShellSortGap)
          ShellSortSwapped = #True
        EndIf
        
      Next
      
    Until ShellSortSwapped = #False
    
  Until ShellSortGap = 1
  
EndProcedure

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< StringSort Descendant operator <<<<<

Procedure StringSortDescendantHerosName(*HeroA.Heros)
  
  ShellSortGap.l = #HEROS_NAME_MAX - 1
  
  Repeat
    
    ShellSortGap >> 1
    
    Repeat
      
      ShellSortSwapped.b = #False
      
      For Index = 0 To (#HEROS_NAME_MAX - 1 - ShellSortGap)
        
        If UCase(GetHerosName(*HeroA, Index)) < UCase(GetHerosName(*HeroA, Index + ShellSortGap))
          Swap GetHerosName(*HeroA, Index), GetHerosName(*HeroA, Index + ShellSortGap)
          ShellSortSwapped = #True
        EndIf
        
      Next
      
    Until ShellSortSwapped = #False
    
  Until ShellSortGap = 1
  
EndProcedure

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< The Copy operator : A = Source : B = Destination <<<<<

Macro CopyHeros(HeroA, HeroB)
  
  For Index = 0 To #HEROS_NAME_MAX - 1
    SetHerosName(HeroB, Index, GetHerosName(HeroA, Index))
  Next

EndMacro

; <<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Debugging macro <<<<<

Macro DebugHeros(HeroA)
  
  For Index = 0 To #HEROS_NAME_MAX - 1
    Debug GetHerosName(HeroA, Index)
  Next
  
EndMacro

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Code generated in : 00.047 seconds <<<<<
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< We fill Myheros structure with names. <<<<<

MyHeros.Heros

SetHerosName(MyHeros, 00, "Zoro")
SetHerosName(MyHeros, 01, "SuperMan")
SetHerosName(MyHeros, 02, "SpiderMan")
SetHerosName(MyHeros, 03, "Freak")
SetHerosName(MyHeros, 04, "Morpheus")
SetHerosName(MyHeros, 05, "Fred")
SetHerosName(MyHeros, 06, "Athena")
SetHerosName(MyHeros, 07, "Zeus")
SetHerosName(MyHeros, 08, "Hercule")
SetHerosName(MyHeros, 09, "Achille")
SetHerosName(MyHeros, 10, "Luke")
SetHerosName(MyHeros, 11, "Anakin")
SetHerosName(MyHeros, 12, "Mace Windu")
SetHerosName(MyHeros, 13, "Yoda")
SetHerosName(MyHeros, 14, "Obiwan")

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< We copy MyHeros to test the sort commands on the same duty. <<<<<

CopyHeros(MyHeros, MyHerosCopy00.Heros)
CopyHeros(MyHeros, MyHerosCopy01.Heros)

; <<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< We run the test <<<<<

Debug "MyHeros original list"
DebugHeros(MyHeros)
Debug ""

Debug "MyHeros Sorted Ascendant"
StringSortAscendantHerosName(MyHerosCopy00)
DebugHeros(MyHerosCopy00)
Debug ""

Debug "MyHeros Sorted Descendant"
StringSortDescendantHerosName(MyHerosCopy01)
DebugHeros(MyHerosCopy01)
Debug ""

; <<<<<<<<<<<<<<<<<<<<<<<
; <<<<< END OF FILE <<<<<
; <<<<<<<<<<<<<<<<<<<<<<<  
Post Reply