BPS #2: Wörter sortieren - Auswertung

Übersicht BlitzBasic Beginners-Corner

Neue Antwort erstellen

Xeres

Moderator

Betreff: BPS #2: Wörter sortieren - Auswertung

BeitragDo, Feb 10, 2011 10:45
Antworten mit Zitat
Benutzer-Profile anzeigen
So, die Zeit ist 'rum!

Das war die Aufgabe

Postet hier eure Ergebnisse, Codes, Gedanken. Lernt von den anderen, seht euch deren Quelltext an und versucht euren eigenen zu verbessern.

Diskussion
Postet zu euren Codes stets eine kurze Erklärung mit euren Gedanken in denen ihr simpel gesagt die Frage "Wieso habe ich XY auf diese Art gelöst?" beantwortet. Beiträge, die nur den Code enthalten werden wir aus dem Thread entfernen.

Nächste Aufgabe
In drei Tagen am Sonntag dem 13. wird die Musterlösung nach editiert und die nächste Aufgabe eingestellt.

Viel Spaß & viel Erfolg!

Musterlösung:
BlitzBasic: [AUSKLAPPEN]
Dim words$(9) ; Das Array zum speichern der Strings wird angelegt

Local i ; Die Zählvariable für die Schleife zur Ausgabe

; Die Liste der Wörter
words(0)="Ich"
words(1)="bin"
words(2)="eine"
words(3)="Ansammlung"
words(4)="unsortierter"
words(5)="Wörter"
words(6)="welche"
words(7)="sortiert"
words(8)="werden"
words(9)="müssen"


SortStrings() ; Die Sortierfunkion wird aufegrufen

For i=0 To 9 ; Die Strings werden sortiert ausgegeben
Print words(i)
Next

WaitKey() ; Damit der Nutzer was zu sehen kriegt
End ; das Programm beenden






Function SortStrings()
; Die benötigten Variablen werden lokal in der Function deklariert
Local i,j,k,tmp$,byte_1,byte_2

; Die übergeordnete Schleife durchläuft die Sortierung 10 mal
For i=0 To 9
; Die nächste Schleife läuft "rückwärts" und sortiert das aktuelle Wort
; bedarfsweise über das darüberliegende ein
For j=9 To 1 Step -1
; Die nächste Schleife dient ausschließlich dem Vergleich der Buchstaben.
; Ist der erste gleich dem Vergleichsbuchstaben wird der zweite verglichen. Ist
; auch dieser gleich, der dritte usw. bis zum Ende des Strings
For k=1 To Len(words(j))
byte_1=Asc(Lower(Mid$(words(j-1),k,1)))
byte_2=Asc(Lower(Mid$(words(j),k,1)))
; Ist das Zeichen nicht gleich springen wir aus der Schleife
If byte_1<>byte_2 Then Exit
Next
; Wir vergleichen das Zeichen und tauschen ggf. die Position
If byte_2<byte_1 Then
tmp=words(j)
words(j)=words(j-1)
words(j-1)=tmp
EndIf
Next
Next
End Function
Win10 Prof.(x64)/Ubuntu 16.04|CPU 4x3Ghz (Intel i5-4590S)|RAM 8 GB|GeForce GTX 960
Wie man Fragen richtig stellt || "Es geht nicht" || Video-Tutorial: Sinus & Cosinus
T
HERE IS NO FAIR. THERE IS NO JUSTICE. THERE IS JUST ME. (Death, Discworld)
  • Zuletzt bearbeitet von Xeres am So, Feb 13, 2011 19:02, insgesamt 2-mal bearbeitet

darth

BeitragDo, Feb 10, 2011 23:18
Antworten mit Zitat
Benutzer-Profile anzeigen
Hallo,

ich habe mich der Aufgabe mal angenommen und zwei verschiedene Möglichkeiten verfasst.

Beides sind ein simple BubbleSorts. Laufzeitverhalten ist O(n^2), also quadratisch. Das heisst, wenn ich die Anzahl Inputs verdopple, vervierfacht sich die nötige Arbeit. Natürlich gibt es bessere Methoden für die Sortierung. Das optimale Maximum das man gefunden hat war O(n log n), das findet man in einem Mergesort und einigen anderen.

Aber hei, Aufgabe war es, ein Maximum von 10 Worten zu sortieren, meiner Meinung nach ist der Rekursionsaufwand eines Mergesorts bei solchen Zahlen grösser als die doppelte Bubblesort Schleife :> Aber ich kann mich täuschen, und ich werde sicher korrigiert werden, falls dies so sein sollte.

Methode 1:

BlitzBasic: [AUSKLAPPEN]
Const MAX_COUNT = 10

Function sortList1( list$[MAX_COUNT], n )
Local switch, a$, b$, valA#, valB#, tmp$

While True
switch = False

For i = 0 To n -2
a = Upper( list[i] )
b = Upper( list[i+1] )

valA = 0
For j = 1 To Len( a )
valA = valA + Asc( Mid(a, j, 1) ) * 100^-j
Next

valB = 0
For j = 1 To Len( b )
valB = valB + Asc( Mid(b, j, 1) ) * 100^-j
Next

If valA > valB
tmp = list[i]

list[i] = list[i+1]
list[i+1] = tmp

switch = True
EndIf
Next

If Not switch
Exit
EndIf
Wend
End Function


Diese Methode verwandelt die Worte in Float-Zahlen, die dann einfach über <> verglichen werden können. Der Vorteil dabei ist, dass der Vergleich einfach ist. Der Nachteil liegt in dem erhöhten Rechenaufwand (die Umwandlung von A zu 0.01 usw). Was bei langen Worten passieren könnte ist, dass die Genauigkeit des Floats nichtmehr ausreicht, um das Wort darzustellen, dann kann es vorkommen, dass zwei Worte nicht richtig sortiert werden.
So alles in Allem ist die Idee eigentlich doof :> Aber ich fand sie witzig genug um ausprobiert zu werden, so there you go.

BlitzBasic: [AUSKLAPPEN]

Function sortList2( list$[MAX_COUNT], n )
Local switch, tmp$

While True
switch = False

For i = 0 To n -2
If sortCompare( list[i], list[i+1] ) > 0
tmp = list[i]

list[i] = list[i+1]
list[i+1] = tmp

switch = True
EndIf
Next

If Not switch
Exit
EndIf
Wend
End Function

Function sortCompare( a$, b$ )
a = Upper( a )
b = Upper( b )

n1 = Len( a )
n2 = Len( b )

n = n1
If n2 < n
n = n2
EndIf

Local v1, v2

For i = 1 To n
v1 = Asc( Mid(a, i, 1) )
v2 = Asc( Mid(b, i, 2) )

If v1 > v2
Return 1
EndIf

If v1 < v2
Return -1
EndIf
Next

Return Sgn( n1 - n2 )
End Function


Methode zwei ist (afaik?) ziemlich standard-mässig. Für den Vergleich wird eine [i]Compare-Funktion aufgerufen, die 1, 0, -1 zurückliefert (je nachdem ob grösser, gleich, kleiner). Dabei wird der ASCII-Code jedes Buchstabens verglichen. Dabei muss man aufpassen, dass A und a zwei unterschiedliche Codes haben, alphabetisch aber gleich (?) sortiert werden sollten. Deshalb habe ich einfach alles Upper-Cased (sprich: asdf -> ASDF, Captain Capslock style).
Der Vergleich bricht ab, falls ein Buchstaben grösser/kleiner ist als ein anderer. Sind sie durchs ganze Wort gleich (asdf <-> asdfa) wird die Wortlänge verglichen. Das längere Wort ist kleiner (ich hoffe das ist richtig? Sonst müsste man das noch kurz ändern und Return Sgn( n2 - n1 ) anpassen..).

Soviel zu meinen Ansätzen. Ich freue mich auf Ideen und Einfälle anderer.
MfG,
Darth
Diese Signatur ist leer.

Xeres

Moderator

BeitragSo, Feb 13, 2011 19:05
Antworten mit Zitat
Benutzer-Profile anzeigen
Danke für deine Teilname darth. Vielleicht findet sich ja nochmal jemand mit einer eigenen Lösung - oder wurde die Aufgabe als zu schwer empfunden? Rückmeldungen helfen uns beim ausarbeiten der Aufgaben.

Die Musterlösung findet sich im Eingangspost.
Win10 Prof.(x64)/Ubuntu 16.04|CPU 4x3Ghz (Intel i5-4590S)|RAM 8 GB|GeForce GTX 960
Wie man Fragen richtig stellt || "Es geht nicht" || Video-Tutorial: Sinus & Cosinus
T
HERE IS NO FAIR. THERE IS NO JUSTICE. THERE IS JUST ME. (Death, Discworld)

Neue Antwort erstellen


Übersicht BlitzBasic Beginners-Corner

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group