Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht Das deutsche QBasic- und FreeBASIC-Forum
Für euch erreichbar unter qb-forum.de, fb-forum.de und freebasic-forum.de!
 
FAQFAQ   SuchenSuchen   MitgliederlisteMitgliederliste   BenutzergruppenBenutzergruppen  RegistrierenRegistrieren
ProfilProfil   Einloggen, um private Nachrichten zu lesenEinloggen, um private Nachrichten zu lesen   LoginLogin
Zur Begleitseite des Forums / Chat / Impressum
Aktueller Forenpartner:

Alphabetische Sortierung eines String-Arrays
Gehe zu Seite 1, 2  Weiter
 
Neues Thema eröffnen   Neue Antwort erstellen    Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht -> Allgemeine Fragen zu FreeBASIC.
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen  
Autor Nachricht
SL



Anmeldungsdatum: 06.12.2009
Beiträge: 43

BeitragVerfasst am: 09.01.2010, 10:54    Titel: Alphabetische Sortierung eines String-Arrays Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden
St_W



Anmeldungsdatum: 22.07.2007
Beiträge: 956
Wohnort: Austria

BeitragVerfasst am: 09.01.2010, 12:30    Titel: Antworten mit Zitat

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 lächeln ).

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
Benutzer-Profile anzeigen Private Nachricht senden
dreael
Administrator


Anmeldungsdatum: 10.09.2004
Beiträge: 2529
Wohnort: Hofen SH (Schweiz)

BeitragVerfasst am: 09.01.2010, 12:33    Titel: Antworten mit Zitat

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"  ' &aelig; => 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
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
volta



Anmeldungsdatum: 04.05.2005
Beiträge: 1876
Wohnort: D59192

BeitragVerfasst am: 09.01.2010, 13:29    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
Jojo
alter Rang


Anmeldungsdatum: 12.02.2005
Beiträge: 9736
Wohnort: Neben der Festplatte

BeitragVerfasst am: 09.01.2010, 13:47    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
St_W



Anmeldungsdatum: 22.07.2007
Beiträge: 956
Wohnort: Austria

BeitragVerfasst am: 09.01.2010, 13:53    Titel: Antworten mit Zitat

Ich glaube aus dem von Volta verlinkten Thread (der von mir erstellt wurde) ging mein obiges Programm hervor, wenn ich mich richtig erinnere.

//edit: Ich habe mir die Arbeit gemacht das obige Programm nach FreeBasic zu portieren. Dafür waren nur etliche "DIM"s und das Löschen der Datentyp-Präfixe nötig.
Download:
http://wurzinger.bplaced.net/files/programmierung/fb/sort_fb.bas
_________________
Aktuelle FreeBasic Builds, Projekte, Code-Snippets unter http://users.freebasic-portal.de/stw/
http://www.mv-lacken.at Musikverein Lacken (MV Lacken)
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
SL



Anmeldungsdatum: 06.12.2009
Beiträge: 43

BeitragVerfasst am: 09.01.2010, 16:28    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden
Sebastian
Administrator


Anmeldungsdatum: 10.09.2004
Beiträge: 5969
Wohnort: Deutschland

BeitragVerfasst am: 09.01.2010, 18:46    Titel: Antworten mit Zitat

Hallo,

hast du dir das so vorgestellt? Telefonbuchsortierung für String-Arrays

Viele Grüße!
Sebastian
_________________

Die gefährlichsten Familienclans | Opas Leistung muss sich wieder lohnen - für 6 bis 10 Generationen!
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
SL



Anmeldungsdatum: 06.12.2009
Beiträge: 43

BeitragVerfasst am: 09.01.2010, 20:01    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden
Sebastian
Administrator


Anmeldungsdatum: 10.09.2004
Beiträge: 5969
Wohnort: Deutschland

BeitragVerfasst am: 09.01.2010, 21:03    Titel: Antworten mit Zitat

Ansonsten hier noch mal ein Versuch der anderen Sortierweise: http://www.freebasic-portal.de/porticula/telefonbuchsortierung-fuer-string-arrays-1040.html lächeln

Übrigens: In der ersten Fassung (#1039) muss es statt
Code:
 ElseIf ((z >= 65) or (z <= 90)) Then

natürlich
Code:
 ElseIf ((z >= 65) and (z <= 90)) Then

heißen.
In der Onlineversion (siehe erster Link) habe ich das bereits korrigiert.
_________________

Die gefährlichsten Familienclans | Opas Leistung muss sich wieder lohnen - für 6 bis 10 Generationen!
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
SL



Anmeldungsdatum: 06.12.2009
Beiträge: 43

BeitragVerfasst am: 09.01.2010, 22:45    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden
Sebastian
Administrator


Anmeldungsdatum: 10.09.2004
Beiträge: 5969
Wohnort: Deutschland

BeitragVerfasst am: 09.01.2010, 23:03    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
dreael
Administrator


Anmeldungsdatum: 10.09.2004
Beiträge: 2529
Wohnort: Hofen SH (Schweiz)

BeitragVerfasst am: 11.01.2010, 20:59    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
SL



Anmeldungsdatum: 06.12.2009
Beiträge: 43

BeitragVerfasst am: 11.01.2010, 22:11    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden
Jojo
alter Rang


Anmeldungsdatum: 12.02.2005
Beiträge: 9736
Wohnort: Neben der Festplatte

BeitragVerfasst am: 11.01.2010, 23:14    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
SL



Anmeldungsdatum: 06.12.2009
Beiträge: 43

BeitragVerfasst am: 12.01.2010, 19:36    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden
SL



Anmeldungsdatum: 06.12.2009
Beiträge: 43

BeitragVerfasst am: 18.01.2010, 22:22    Titel: Sub’s ohne Deklaration? Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden
MOD
Fleißiger Referenzredakteur


Anmeldungsdatum: 10.09.2007
Beiträge: 1003

BeitragVerfasst am: 18.01.2010, 22:27    Titel: Antworten mit Zitat

Wenn die Unterprogramme vor dem Einstiegspunkt sind, dann sind sie damit deklariert. War schon immer so.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Stueber



Anmeldungsdatum: 07.07.2008
Beiträge: 202

BeitragVerfasst am: 18.01.2010, 22:30    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden
SL



Anmeldungsdatum: 06.12.2009
Beiträge: 43

BeitragVerfasst am: 18.01.2010, 22:40    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden
Beiträge der letzten Zeit anzeigen:   
Neues Thema eröffnen   Neue Antwort erstellen    Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht -> Allgemeine Fragen zu FreeBASIC. Alle Zeiten sind GMT + 1 Stunde
Gehe zu Seite 1, 2  Weiter
Seite 1 von 2

 
Gehe zu:  
Du kannst keine Beiträge in dieses Forum schreiben.
Du kannst auf Beiträge in diesem Forum nicht antworten.
Du kannst deine Beiträge in diesem Forum nicht bearbeiten.
Du kannst deine Beiträge in diesem Forum nicht löschen.
Du kannst an Umfragen in diesem Forum nicht mitmachen.

 Impressum :: Datenschutz