Sortierproblem: Strings + Zahlen zusammen sortieren

Übersicht BlitzMax, BlitzMax NG Allgemein

Neue Antwort erstellen

 

danielos

Betreff: Sortierproblem: Strings + Zahlen zusammen sortieren

BeitragMo, Feb 15, 2010 13:17
Antworten mit Zitat
Benutzer-Profile anzeigen
Moin zusammen! Smile

Also ich hab da grad ein kleines Problem: Ich möchte, dass meine Sortierfunktion Strings alphabetisch ordnet, die MÖGLICHERWEISE Zahlen enthalten könnten (aber nicht müssen..)
Also sowas wie:

"Scary Movie 1" oder "Konzert Nr. 31"

Meine Ursprungsidee war, die einzelnen Ziffern jeweils Buchstaben zu ersetzen, also wird "Scary Movie 1" dann zu "Scary Movie A" oder "Konzert Nr. 31" zu "Konzert Nr. CA"
Damit kann meine Sortierfunktion auch umgehen, ABER:
das funktioniert nur, solange die Zahlen < 10 sind.

Das Sortieren findet innerhalb einer List statt, die Standard-Sort() - Methode hab mit meiner eigenen Funktion überschrieben. Die liefert den Wert von Text1.Compare(Text.2) zurück (möglicherweise liegts auch daran ?? )

Das ganze ist möglicherweise ganz trivial, aber ich komm grad trotzdem nicht weiter Sad

MfG

Danielos

BladeRunner

Moderator

BeitragMo, Feb 15, 2010 13:27
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich verstehe dein Problem nicht ganz? Die Standardsortierung bindet doch auch zahlen mit ein?
Zu Diensten, Bürger.
Intel T2300, 2.5GB DDR 533, Mobility Radeon X1600 Win XP Home SP3
Intel T8400, 4GB DDR3, Nvidia GF9700M GTS Win 7/64
B3D BMax MaxGUI

Stolzer Gewinner des BAC#48, #52 & #92
 

danielos

BeitragMo, Feb 15, 2010 13:35
Antworten mit Zitat
Benutzer-Profile anzeigen
Die Standardsortierung vielleicht schon, aber dieses Text1.Compare(Text.2) leider nicht...
Das Text1.Compare(Text.2) sollte was positives zurückliefern, wenn Text1 VOR Text2 angeordnet werden soll, ansonsten was negatives (vielleicht ist es auch andersrum, aber das ist jetzt nicht das Problem ^^ )
Das klappt mit Standardtexten schon, aber nicht, wenn sie Zahlen enthalten...

Wie gesagt, ggf. gibs auch einfach was besseres als dieses .Compare() (?)

Silver_Knee

BeitragMo, Feb 15, 2010 13:58
Antworten mit Zitat
Benutzer-Profile anzeigen
Das Problem ist wahrscheinlich, dass zahlen nicht Zehnerpotenzgerecht sortiert werden:

1
10
11
12
2
3
4
5
6
7
8
9

oder?

Midimaster

BeitragMo, Feb 15, 2010 14:11
Antworten mit Zitat
Benutzer-Profile anzeigen
Deine Idee, die Zahlen in Buchstaben zu wandeln ist im Prinzip schon der richtige Ansatz. Allerdings solltest Du nicht die einzelenen Ziffern konvertieren, sondern beim Auftreten einer Ziffern im String auch alle weiteren folgenden Ziffern noch zu berücksichtigen (bis z.b. ein anderes Zeichen gefunden wird). So dass in einen "Konzert Nr 32" nicht nur die 3 sondern die 32 gefunden wird. Nun ergänzt du alle Zahlen mit führenden Nullen: z.b. "00000032" und trimst sie auf z.b. 5 Zeichen von rechts "00032". Dies fügst du nun in den String an die Stelle der 32 ein. Die Sortierung wird nun korrekt sein.
 

danielos

BeitragMo, Feb 15, 2010 14:26
Antworten mit Zitat
Benutzer-Profile anzeigen
Danke für die Antworten!

@Silver_Knee

Ja exakt so schaut die falsche Sortierung dann aus!


@Midimaster

Ich glaube, dass ich die Idee auch schon hatte (wenn ich sie richtig verstanden habe Smile ), allerdings müsste ich doch dann ne Schleife bis 1000 (oder höher) einbauen, wenn die Zahlen bis 1000 (oder höher) gehen, oder? Das wär nämlich schon ne ganz schöne Rechenarbeit, wenn das PRO EINTRAG geschehen soll.

Deshalb war auch meine Frage, obs dafür ne bessere Lösung gibt, ich komm grad nicht drauf ^^

Xeres

Moderator

BeitragMo, Feb 15, 2010 14:32
Antworten mit Zitat
Benutzer-Profile anzeigen
Was sollte das für eine Schleife sein...?
Ich würde so ansetzten:
1. String untersuchen und alles was keine Zahl ist, durch Leerzeichen ersetzen.
2. Multiple Leerzeichen durch ein einzelnes Ersetzen.
3. Alle Zahlen per Split(" ") extrahieren.
4. Zahlen wie Midimaster vorschlug formatieren.
5. Zahlen im Originalstring damit ersetzen und sortieren (wobei du einen Originalstring zum anzeigen unverändert lässt).
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)

Silver_Knee

BeitragMo, Feb 15, 2010 14:35
Antworten mit Zitat
Benutzer-Profile anzeigen
du kannst pro Eintrag speichern wo die Zahl gefunden wurde und insgesammt was die höchste 10erpotenz ist:

Hase 3
[höchste 10erpotenz:1]
Hase 4
[bleibt]->Nach Hase3

Hase 1
[bleibt]->Vor Hase 3

Hase 10
[höchste 10erpotzenz:2] -> Zurück und Liste korrigieren
Hase 03
Hase 04
Hase 05
Hase 10

etc.
 

danielos

BeitragMo, Feb 15, 2010 15:27
Antworten mit Zitat
Benutzer-Profile anzeigen
@Xeres:

Um eine (z.B) dreistellige Zahl zu finden, müsste ich doch schreiben:


Code: [AUSKLAPPEN]

For Local i:int = Null to 999
      Local result:int = Instr(StringToTest$,String(i))

      If result
               'blablabla
      EndIf
Next


Das meinte ich mit Schleife...klar dass das dann geht, aber ich wollte halt iwie vermeiden, dass da immer tausend Zahlen überprüft werden Confused (oder gibts ne bessere Methode?)
 

Dreamora

BeitragMo, Feb 15, 2010 16:03
Antworten mit Zitat
Benutzer-Profile anzeigen
Wenn der code nicht als joke gedacht ist dann fürchte ich, hast du ganz andere probleme als sortieren, weils an den basics so derbe happert das du garnicht erst zeit fürs sortieren verschwenden brauchst ...
die logik von deinem is aust prinzip noch nicht mal im bereich von dem was oben geschrieben wurde


wenn du eine 10 stellige zahl hättest, hast du maximal 10 schleifen durchläufe.
Bei jedem dieser durchläufe dividierst du die zahl durch 10 um sie um eine 10er potenz zu reduzieren (also am anfang 1er, nächster durchlauf 10er stelle, dann 100er, 1000er, ...) und schreibst die letzte ziffer vorne an den "resultat string". wenn du das mit int division machst, wirst du so automatisch die korrekte zahl mit 0en vorne dran bekommen.

alternativ: schreib das ganze ding in einen string und dann einfach loop die 0en vorne dran hängt und zwar soviele wie gewuenschteAnzahlStellen - len(zahlenString)
Ihr findet die aktuellen Projekte unter Gayasoft und könnt mich unter @gayasoft auf Twitter erreichen.
  • Zuletzt bearbeitet von Dreamora am Mo, Feb 15, 2010 16:05, insgesamt einmal bearbeitet

Artemis

BeitragMo, Feb 15, 2010 16:03
Antworten mit Zitat
Benutzer-Profile anzeigen
https://www.blitzforum.de/foru...hp?t=34005

Kleines Beispiel (quick'n'dirty):
BlitzMax: [AUSKLAPPEN]
SuperStrict
Import artemis.natcompare

Type a
Global m:Int = False
Function Create:a(b$)
Local o:a = New a
o.b = b
Return o
EndFunction
Field b$
Method compare:Int(c:Object)
If Not a(c) Then Return 0
If a.m Then
Return NatCompare(Self.b, a(c).b)
Else
Return Self.b.compare(a(c).b)
EndIf
EndMethod
EndType

Local l:TList = New TList

Rem
Local i$ = Input("String: ")
While i <> ""
Local o:a = New a
o.b = i
l.addlast(o)
i$ = Input("String: ")
Wend
EndRem

l.addlast(a.Create("Test 35"))
l.addlast(a.Create("Test 2"))
l.addlast(a.Create("Test 4 plus Zeugs"))
l.addlast(a.Create("Ich habe 254.023 Tests gemacht"))
l.addlast(a.Create("Ich habe 00254.0023 Tests gemacht"))
l.addlast(a.Create("Ich habe 254.0023 Tests gemacht"))

Print ""
Print "unsortiert"
For Local o:a = EachIn l
Print o.b
Next

Print ""
Print "blitz-sortiert"
l.sort()
For Local o:a = EachIn l
Print o.b
Next

Print ""
Print "nat-sortiert"
a.m = True
l.sort()
For Local o:a = EachIn l
Print o.b
Next

Xeres

Moderator

BeitragMo, Feb 15, 2010 16:06
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich empfehle mal etwas String Theory.
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)
 

danielos

BeitragMo, Feb 15, 2010 16:36
Antworten mit Zitat
Benutzer-Profile anzeigen
okay... die spontanen Ideen sind nicht immer die besten Rolling Eyes


Artemis, vielen Dank, das hat mir sehr geholfen! Smile Smile

Midimaster

BeitragMo, Feb 15, 2010 16:38
Antworten mit Zitat
Benutzer-Profile anzeigen
Nee Danielos, das geht viel einfacher:

ein erster Ansatz:

Beim Vergleichen wandelst du alle Zahlen-Parts des Strings (da noch mit beliebige Stellenanzahl) in Zahlenparts mit fester Anzahl Stellen:

Beispiel

Konzert No 17 Satz 6
Konzert No 2 Satz 8

werden zu
Konzert No 00017 Satz 00006
Konzert No 00002 Satz 00008

und damit kannst du jetzt den Vergleich machen.

Das Finden der Ziffern geht doch ganz leicht, in dem Du dich Stelle für Stelle durch den SuchStrings voransuchst, bis du auf eine Ziffer stößt.
For i=1 to len(SS$)...
If Mid$(SS$,i,1....

Dann isolierst Du die dort gefundene Zahl.
Z%=val(Mid$(SS$,i,-1)

Wandelst sie in einen NeuenString,merke dir die Anzahl der Ziffern in N% den du dann auf 5 Stellen erweiterst.
NZ$=Right("00000" + Z%,5)

Dann wird der linke Teil des Suchstrings + NeuerString + RechterTeil des Suchstrings wieder zusammengesetzt.
SS$=Left(SS$,i) + NZ$ + Right(SS$,i+N%,-1)

Das gleiche mit Stellen, die möglicherweise noch weiter hinten im suchstring kommen. Das gleiche auch mit dem Compare-String. Und dann kannst du aus dem Suchstring und dem Comparestring


so, oder ähnlich...
  • Zuletzt bearbeitet von Midimaster am Mo, Feb 15, 2010 19:52, insgesamt einmal bearbeitet

Artemis

BeitragMo, Feb 15, 2010 19:17
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich wär mir aber nicht so sicher, dass das bei dir viel schneller läuft. Hey, und warum soll man das Rad neu erfinden, wenn das ja schon jemand (in dem Fall der Autor von dem C-Code) gemacht hat?

EDIT: Alles klar Wink
  • Zuletzt bearbeitet von Artemis am Mo, Feb 15, 2010 20:25, insgesamt einmal bearbeitet

Midimaster

BeitragMo, Feb 15, 2010 19:51
Antworten mit Zitat
Benutzer-Profile anzeigen
ähm,, peinlich Embarassed ich meinte nicht "Nee, Artemis", sondern "Nee,Danielos"

Artemis, dein Vorschlag is natürlich toll!

Neue Antwort erstellen


Übersicht BlitzMax, BlitzMax NG Allgemein

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group