Vorheriges Thema anzeigen :: Nächstes Thema anzeigen |
Autor |
Nachricht |
SL
Anmeldungsdatum: 06.12.2009 Beiträge: 43
|
Verfasst am: 09.01.2010, 10:54 Titel: Alphabetische Sortierung eines String-Arrays |
|
|
In der FB-Befehls-Referenz steht unter Basic-Grundlagen / Ausdrücke und Operatoren / Stringoperationen unter anderem Folgendes: Prüfen, ob ein String alphabetisch vor einem anderen steht (String1 < String2).
Dieser Satz ist so leicht missverständlich. Besser wäre vielleicht folgende Darstellung: Prüfen, ob ein String alphabetisch (entsprechend der Sortierung nach ASCII-Codes) vor einem anderen steht (String1 < String2).
Womit ich nun beim Thema bin: Ich suche eine Routine, welche genau das tut, was oben beschrieben wurde, jedoch nicht nach ASCII-Code vergleicht (sortiert) sondern nach dem deutschen Alphabet. Hier gibt es bekanntlich so Gemeinheiten wie Groß- und Kleinbuchstaben und Sonderbuchstaben wie ä, ü, ö, ß. Auch Sonderzeichen wie ? oder $ oder - innerhalb eines Strings können bei einer Sortierung nach ASCII zu sehr seltsamen Ergebnissen führen. Ein kurze Einführung in alphabetische Sortierung ist hier: http://de.wikipedia.org/wiki/Alphabetische_Sortierung
Hat jemand bereits so eine Sortier-Routine? Beispielsweise eine „Telefonbuchsortierung“ (Im Freebasic-Portal / Code-Beispiele / kleine Helferlein fand ich nichts) |
|
Nach oben |
|
 |
St_W

Anmeldungsdatum: 22.07.2007 Beiträge: 956 Wohnort: Austria
|
Verfasst am: 09.01.2010, 12:30 Titel: |
|
|
In QBasic hab ich soetwas schon einmal implementiert. Hier prüfe ich die ASCII Codes vorher und rechne diese in ein eigenes Sortierungssystem um, sodass auch Umlaute, Sonderzeichen, Groß-/Kleinbuchstaben richtig sortiert werden (sollten ).
Ich weiß nicht wie schlecht/gut mein selbstgebastelter Algorithmus ist und wie zuverlässig das Programm ist. Weiters müsste es natürlich in den FreeBasic Dialekt umgeschrieben werden, was aber normalerweise kein so großer Aufwand ist.
Das Programm enthält neben einer Sortiermethode für Strings auch noch eine für Zahlen.
Vielleicht ist es ja nützlich:
http://wurzinger.bplaced.net/files/programmierung/qb/sort.bas
(Ist im DOS-OEM Zeichensatz kodiert, also werden im Windows Editor die Sonderzeichen falsch dargestellt) _________________ Aktuelle FreeBasic Builds, Projekte, Code-Snippets unter http://users.freebasic-portal.de/stw/
http://www.mv-lacken.at Musikverein Lacken (MV Lacken) |
|
Nach oben |
|
 |
dreael Administrator

Anmeldungsdatum: 10.09.2004 Beiträge: 2529 Wohnort: Hofen SH (Schweiz)
|
Verfasst am: 09.01.2010, 12:33 Titel: |
|
|
Du musst Deine Sortierschlüssel beispielsweise in ein Hilfsarray konvertieren oder Funktion aufrufen. Als erstes würde ich eine FUNCTION programmieren, welche wie folgt arbeitet:
Code: | DECLARE FUNCTION verglstr$(s$)
PRINT verglstr$("Äußere Ölbüchse")
PRINT verglstr$("Les élèves drôles") |
Ergebnis hat Folgendes geschrieben: | AUSSERE OLBUCHSEN
LES ELEVES DROLES |
=> Nun kannst entweder direkt in der Sortierroutine (spart Speicher, dafür u.U. langsamer)
Code: | SUB sort(s$())
FOR i%=LBOUND(s$) TO UBOUND(s$) - 1
FOR j%=i% + 1 TO UBOUND(s$)
IF verglstr$(s$(j%)) < verglstr$(i%)) THEN
SWAP s$(i), s$(j%)
END IF
NEXT j%
NEXT i%
END SUB |
oder mit Hilfsarray (schneller, dafür mehr Speicher nötig) arbeiten:
Code: | SUB sort2(s$())
DIM hilf$(LBOUND(s$) TO UBOUND(s$))
FOR i%=LBOUND(s$) TO UBOUND(s$)
hilf$(i%) = verglstr$(s$(i%))
NEXT i%
FOR i%=LBOUND(s$) TO UBOUND(s$) - 1
FOR j%=i% + 1 TO UBOUND(s$)
IF hilf$(j%) < hilf$(i%) THEN
SWAP s$(i), s$(j%)
SWAP hilf$(i), hilf$(j%)
END IF
NEXT j%
NEXT i%
ERASE hilf$
END SUB |
Implementierungshinweis verglstr$(): Am besten mit Tabelle arbeiten, z.B. ein Array definieren:
Code: | DIM convtab$(0 TO 255)
' Ziel:
' convtab$(223) = "SS"
' convtab$(65) = "A"
' convtab$(97) = "A"
' usw.
FOR i%=0 TO 127
convtab$(i%)=UCASE$(CHR$(i%))
NEXT i%
' Annahme: Arbeitet FreeBasic immer noch mit Codepage 437?
FOR i%=0 TO 16
convtab$(i% + 128) = MID$("CUEAAAACEEEIIIAAE", i% + 1, 1)
NEXT i%
convtab$(145) = "AE" ' æ => Doppelt wie "ß"!
' usw.
FUNCTION verglstr$(s$)
SHARED convtab$
h$ = ""
FOR i%=1 TO LEN(s$)
h$ = h$ + convtab$(ASC(MID$(s$, i%, 1)))
NEXT i%
verglstr$ = h$
END FUNCTION |
Hinweis Codepage:
http://de.wikipedia.org/wiki/Codepage_437
Codebeispiele nicht getestet! _________________ Teste die PC-Sicherheit mit www.sec-check.net |
|
Nach oben |
|
 |
volta
Anmeldungsdatum: 04.05.2005 Beiträge: 1876 Wohnort: D59192
|
Verfasst am: 09.01.2010, 13:29 Titel: |
|
|
Forensuche: sortieren
siehe http://forum.qbasic.at/viewtopic.php?t=5716 _________________ Warnung an Choleriker:
Dieser Beitrag kann Spuren von Ironie & Sarkasmus enthalten.
Zu Risiken & Nebenwirkungen fragen Sie Ihren Therapeuten oder Psychiater. |
|
Nach oben |
|
 |
Jojo alter Rang

Anmeldungsdatum: 12.02.2005 Beiträge: 9736 Wohnort: Neben der Festplatte
|
Verfasst am: 09.01.2010, 13:47 Titel: |
|
|
Volta: Da ist aber keine telefonbuch-sortierung dabei. _________________ » Die Mathematik wurde geschaffen, um Probleme zu lösen, die es nicht gäbe, wenn die Mathematik nicht erschaffen worden wäre.
 |
|
Nach oben |
|
 |
St_W

Anmeldungsdatum: 22.07.2007 Beiträge: 956 Wohnort: Austria
|
|
Nach oben |
|
 |
SL
Anmeldungsdatum: 06.12.2009 Beiträge: 43
|
Verfasst am: 09.01.2010, 16:28 Titel: |
|
|
Ich habe mich vielleicht etwas ungeschickt ausgedrückt. Mir geht es nicht um die Sortierung eines String-Arrays (dafür gibt es genügend Programm-Beispiele) sondern um die Vorstufe zum Sortieren, nämlich den Vergleich von zwei String-Variablen, um festzustellen welcher von beiden kleiner ist.
Dabei sollen nicht die ASCII-Codes als Vergleichsmaßstab dienen, sondern die im deutschen Sprachraum übliche alphabetische Sortierung (siehe Hinweis auf Wiki im ersten Beitrag)
Ein gutes Beispiel ist MS-Word. Hier kann man Text nach DIN sortieren. Dazu einfach eine Tabelle mit z. B. 5 Zeilen eröffnen und jeweils in der erste Spalte irgendeinen Text eingeben. Dann im Menü Tabelle / Sortieren / Sortierschlüssel den Text für die erste Spalte sortieren. Man sieht dann sehr gut, nach welchen Regeln sortiert wird.
Man bräuchte also eine Funktion die so bezeichnet wird:
Funktion_Zeichenkettenvergleich_DIN_5007_2 (Zeichenkette_1, Zeichenkette_2)
Ist die Zeichenkette_1 kleiner als Zeichenkette_2 gibt die Funktion 1 zurück, ansonsten 0. |
|
Nach oben |
|
 |
Sebastian Administrator

Anmeldungsdatum: 10.09.2004 Beiträge: 5969 Wohnort: Deutschland
|
|
Nach oben |
|
 |
SL
Anmeldungsdatum: 06.12.2009 Beiträge: 43
|
Verfasst am: 09.01.2010, 20:01 Titel: |
|
|
Danke, genau das ist es.
Du hast aber, was nicht notwendig wäre, die Unterscheidung zwischen Klein- und Großbuchstaben aufgehoben. Hier würde die Sortierung nach ASCII sogar ohne Änderung mit der „Telefonbuchsortierung“ übereinstimmen, da Großbuchstaben Vorrang gegenüber Kleinbuchstaben haben.
Am besten, du änderst in deinem Code-Teil bei „Testnamen“ den Eintrag „Mueller“ in „mueller“, dann siehst du sofort was ich meine.
Edit: So einfach wie zuerst gedacht ist das mit Groß- und Kleinbuchstaben doch nicht. Die ASCII-Sortierung hilft hier nicht weiter. Die würde so sortieren: A, B, a. Richtig wäre aber: A, a, B.
Edit II: Ich muß alles zurücknehmen. Dein Code ist so absolut korrekt! Word sortiert genauso wie dein Code. Ein Beispiel aus einer Word-Sortierung: m, M, Maat, mager, Mönch, Müller
Hoffentlich war das mein letztes Edit!! |
|
Nach oben |
|
 |
Sebastian Administrator

Anmeldungsdatum: 10.09.2004 Beiträge: 5969 Wohnort: Deutschland
|
|
Nach oben |
|
 |
SL
Anmeldungsdatum: 06.12.2009 Beiträge: 43
|
Verfasst am: 09.01.2010, 22:45 Titel: |
|
|
Die zweite Version sortiert zunächst nach Großbuchstaben, dann nach Kleinbuchstaben. Es ist Geschmackssache, welche alphabetische Sortierung einem besser gefällt. Ich würde mittlerweile die erste Version bevorzugen.
Als Anfänger-Projekt versuche ich gerade ein „Karteikasten-Programm“ in Form einer Adressenverwaltung zu schreiben. Damit können Datensätze (= Adressen) gesucht, zugefügt, gelöscht oder geändert werden. Für den Such-Index werde ich – deine Zustimmung vorausgesetzt – die von dir hier vorgestellte „Telefonbuchsortierung“ verwenden. |
|
Nach oben |
|
 |
Sebastian Administrator

Anmeldungsdatum: 10.09.2004 Beiträge: 5969 Wohnort: Deutschland
|
Verfasst am: 09.01.2010, 23:03 Titel: |
|
|
SL hat Folgendes geschrieben: | deine Zustimmung vorausgesetzt |
Die Lizenzbedingungen, die auf der MIT-Lizenz basieren, sind am Anfang des Quelltexts angegeben. Du kannst den Source beliebig verwenden, allerdings ausschließlich auf eigene Gefahr. Ich übernehme keine Gewährleistung dafür, dass der experimentelle Quelltext bestimmte Zwecke erfüllt oder fehlerfrei ist. _________________
Die gefährlichsten Familienclans | Opas Leistung muss sich wieder lohnen - für 6 bis 10 Generationen! |
|
Nach oben |
|
 |
dreael Administrator

Anmeldungsdatum: 10.09.2004 Beiträge: 2529 Wohnort: Hofen SH (Schweiz)
|
Verfasst am: 11.01.2010, 20:59 Titel: |
|
|
SL hat Folgendes geschrieben: | Man bräuchte also eine Funktion die so bezeichnet wird:
Funktion_Zeichenkettenvergleich_DIN_5007_2 (Zeichenkette_1, Zeichenkette_2) |
Und genau diese Funktion musst Du halt bei meinem Beispiel als
Code: | FUNCTION Zeichenkettenvergleich_DIN_5007_2% (Zeichenkette_1$, Zeichenkette_2$)
IF verglstr$(Zeichenkette_1$) < verglstr$(Zeichenkette_2$) THEN
Zeichenkettenvergleich_DIN_5007_2% = 1
ELSE
Zeichenkettenvergleich_DIN_5007_2% = 0
END IF
END FUNCTION |
umsetzen. Zu verglstr$() siehe meinen oberen Beitrag.
Habe ansonsten noch
http://de.wikipedia.org/wiki/Alphabetische_Sortierung
kurz überflogen: Jetzt musst Du einfach die convtab$() passend zu dieser DIN-Norm aufbauen. _________________ Teste die PC-Sicherheit mit www.sec-check.net |
|
Nach oben |
|
 |
SL
Anmeldungsdatum: 06.12.2009 Beiträge: 43
|
Verfasst am: 11.01.2010, 22:11 Titel: |
|
|
Mittlerweile ist mir der Weg einigermaßen klar. Was ich bei deinem Code allerdings nicht verstehe, ist die Verwendung von "SHARED“ innerhalb einer Funktion (in deinem Code, Teil 3 ganz unten). Wenn ich SHARED in einer SUB/Funktion verwende, meckert mich der Compiler immer an. Was mache ich da falsch? |
|
Nach oben |
|
 |
Jojo alter Rang

Anmeldungsdatum: 12.02.2005 Beiträge: 9736 Wohnort: Neben der Festplatte
|
Verfasst am: 11.01.2010, 23:14 Titel: |
|
|
FB ist ein wenig sauberer als QB und somit funktioniert das "nach außen bekannt machen" von Variablen mittels SHARED nicht mehr. _________________ » Die Mathematik wurde geschaffen, um Probleme zu lösen, die es nicht gäbe, wenn die Mathematik nicht erschaffen worden wäre.
 |
|
Nach oben |
|
 |
SL
Anmeldungsdatum: 06.12.2009 Beiträge: 43
|
Verfasst am: 12.01.2010, 19:36 Titel: |
|
|
Noch eine kleine Anmerkung zur "Telefonbuchsortierung". Sobald Ziffern ins Spiel kommen, wird es wieder chaotisch, wenn nach ASCII-Codes sortiert wird. Da würden dann die Zeichenketten „A9“ und „A123“ so sortiert werden: A123, A9, was eigentlich jeder Logik widerspricht. Die Zeichenketten „B9 und „C123“ werden hingegen – wie nicht anders zu erwarten - richtig sortiert.
Im "Telefonbuch" dürften obige Zeichenketten eher nicht vorkommen. Doch beispielsweise bei Artikelnummern gibt es häufig Bezeichnungen aus einer Kombination von Buchstaben und Ziffern. Übrigens, die Sortier-Funktion von MS Word kommt bei so gemeinen Beispielen auch ganz nett ins Stolpern! |
|
Nach oben |
|
 |
SL
Anmeldungsdatum: 06.12.2009 Beiträge: 43
|
Verfasst am: 18.01.2010, 22:22 Titel: Sub’s ohne Deklaration? |
|
|
Bei obigen Code-Beispiel von Sebastian (Sortierung eines Arrays) ist mir erst jetzt aufgefallen, dass die Unterprogramme nicht deklariert sind!
Trotzdem läuft das Programm wie am Schnürchen. Das liegt daran, dass sämtliche Unterprogramme vor dem Modulebenen-Code angeordnet sind.
In der Referenz steht davon kein Wort. Läuft dies unter "quick and dirty" oder sind Deklarationen in Zukunft "offiziell" obsolet? (Falls der Modulebenen-Code erst nach den Unterprogrammen angeordnet ist,) |
|
Nach oben |
|
 |
MOD Fleißiger Referenzredakteur

Anmeldungsdatum: 10.09.2007 Beiträge: 1003
|
Verfasst am: 18.01.2010, 22:27 Titel: |
|
|
Wenn die Unterprogramme vor dem Einstiegspunkt sind, dann sind sie damit deklariert. War schon immer so. |
|
Nach oben |
|
 |
Stueber
Anmeldungsdatum: 07.07.2008 Beiträge: 202
|
Verfasst am: 18.01.2010, 22:30 Titel: |
|
|
Du musst eine Funktion deklarieren, damit sie vor der Implementierung aufrufbar ist.
Wenn man das aber garnicht muss kann man die Dekleration weglassen.
Durch das Implementieren werden sie ausserdem auch deklariert.
Trotzdem ist Dekleration nützlich:
- Wenn man den Code übersichtlich machen will, da viele Funktionen schnell unübersichtlich werden.
- Wenn man aus einer Bibliothek laden will.
- Wenn man sowas hat:
Code: | sub a ()
print "Hallo"
b()
end sub
sub b()
print "Welt"
a()
end sub
a() |
Abgesehen davon, das der Code eine Endlosschleife ergibt, gibt es noch ein Problem. Woher soll FB in Zeile 3 schon etwas vom sub b() wissen? Vertauscht man sub a und sub b hat man das Problem nur umgedreht. |
|
Nach oben |
|
 |
SL
Anmeldungsdatum: 06.12.2009 Beiträge: 43
|
Verfasst am: 18.01.2010, 22:40 Titel: |
|
|
Stueber hat Folgendes geschrieben: | Abgesehen davon, das der Code eine Endlosschleife ergibt, gibt es noch ein Problem. Woher soll FB in Zeile 3 schon etwas vom sub b() wissen? Vertauscht man sub a und sub b hat man das Problem nur umgedreht. |
An so was Ähnliches habe ich auch bereits gedacht. Also weiterhin Funktionen deklarieren.
Apropos „Deklaration“. Wieso nimmt einem diese (rein formale) Arbeit die IDE nicht ab. Soweit ich mich erinnere, gab's das früher mal bei QB. |
|
Nach oben |
|
 |
|