Mein Quicksort funktioniert nicht - Bitte um Hilfe bei der Fehlersuche
Hallo liebe Leute,
ich will mich gar nicht darüber streiten ob selbstgestrickte Arrays in Batches Sinn machen oder nicht. Letztlich ist es in anderen Programmiersprachen auch nicht anders. Es ist reservierter Speicher, dem ich Namen gebe. Sonst nichts. Eine lib stellt die Arrayfunktionen zur Verfügung. Bei mir inzwischen auch. Ich finde es praktisch, weil für mein Gefühl der Code aufgeräumter aussieht. Und es ist für mich einfacher, es vielleicht auch in eine andere Programmiersprache zu portieren oder Progs aus anderen Programmiersprachen als Batch zu realisieren. Egal. Darum geht es mir jetzt nicht.
Ich habe einen Pseudocode Quicksort umgesetzt und er funktioniert nicht. Ich finde den Fehler nicht. Vielleicht kann mir jemand auf die Sprünge helfen. Mein Bubblesort funktioniert einwandfrei. In beide Richtungen. Es liegt also nicht an den Arrayfunktionen. Kann Quicksort eigentlich auch absteigend sortieren? So ganz klar ist mir der Algorithmus noch nicht. Das Prinzip schon. Aber irgendwas fehlt mir noch.
Irgendwas fehlt mir - aber was? Das Pivotelement wird richtig gesetzt, die ersten Tauschaktionen laufen richtig. Aber dann wird nicht weitersortiert. Die Gotos habe ich eingebaut, nachdem ich verzweifelt versucht habe eine Endlosschleife zu konstruieren.
geht nicht. der Job bleibt bei meinem CMD stehen. Bei
auch. Das hier geht auch nicht
Ich habe hier gelegentlich auch
gesehen. Da bekomme ich auch eine Fehlermeldung. Die Zählvariable muss zwei Prozentzeichen haben und ich kann ihr auch keinen Wert zuweisen.
Also doch zwei Fragen.
1. Was ist bei meinem qsort falsch?
2. Gibt es eine andere Möglichkeit, eine Endlosschleife zu bauen?
Vielen Dank für Euer Interesse
LG
Leo
ich will mich gar nicht darüber streiten ob selbstgestrickte Arrays in Batches Sinn machen oder nicht. Letztlich ist es in anderen Programmiersprachen auch nicht anders. Es ist reservierter Speicher, dem ich Namen gebe. Sonst nichts. Eine lib stellt die Arrayfunktionen zur Verfügung. Bei mir inzwischen auch. Ich finde es praktisch, weil für mein Gefühl der Code aufgeräumter aussieht. Und es ist für mich einfacher, es vielleicht auch in eine andere Programmiersprache zu portieren oder Progs aus anderen Programmiersprachen als Batch zu realisieren. Egal. Darum geht es mir jetzt nicht.
Ich habe einen Pseudocode Quicksort umgesetzt und er funktioniert nicht. Ich finde den Fehler nicht. Vielleicht kann mir jemand auf die Sprünge helfen. Mein Bubblesort funktioniert einwandfrei. In beide Richtungen. Es liegt also nicht an den Arrayfunktionen. Kann Quicksort eigentlich auch absteigend sortieren? So ganz klar ist mir der Algorithmus noch nicht. Das Prinzip schon. Aber irgendwas fehlt mir noch.
:qsort
Rem Ein Arrey wird übergeben und 2 Indizes
SET QUICK.ARRAY=%1
SET LOW.INDEX=%2
SET HIGH.INDEX=%3
SET /a i=%LOW.INDEX%
SET /a j=%HIGH.INDEX%
Rem Arraymitte errechnen
SET /a HELP=%LOW.INDEX%+%HIGH.INDEX%
SET /a P=%HELP%/2
Rem das PIVOT Element wird festgelegt. Mitte Array
setlocal enabledelayedexpansion
call lib getval %QUICK.ARRAY% %P% PIVOT
endlocal & SET PIVOT=%PIVOT%
Rem das Tauschelement von links wird gesucht
:LINKS_NEXT
setlocal enabledelayedexpansion
call lib getval %QUICK.ARRAY% %i% WERT_LINKS
endlocal & SET WERT_LINKS=%WERT_LINKS%
IF %WERT_LINKS% LSS %PIVOT% (
set /a i+=1
goto LINKS_NEXT
)
Rem das Tauschelement von rechts wird gesucht
:RECHTS_NEXT
setlocal enabledelayedexpansion
call lib getval %QUICK.ARRAY% %j% WERT_RECHTS
endlocal & SET WERT_RECHTS=%WERT_RECHTS%
IF %WERT_RECHTS% GTR %PIVOT% (
set /a j-=1
goto RECHTS_NEXT
)
Rem solange der Index von links kleinergleich Index von rechts
Rem werden die Elemente getauscht
IF %i% LEQ %j% (
setlocal enabledelayedexpansion
call lib getval !QUICK.ARRAY! %i% Z1
call lib getval %QUICK.ARRAY% %j% Z2
Rem Ausgabe zu Kontrollzwecken
echo vorher
ECHO %QUICK.ARRAY%[%i%]=!Z1!
ECHO %QUICK.ARRAY%[%j%]=!Z2!
Rem die Elemente werden getauscht
SET %QUICK.ARRAY%[%i%]=!Z2!
SET %QUICK.ARRAY%[%j%]=!Z1!
Rem Ausgabe zu Kontrollzwecken
call lib getval !QUICK.ARRAY! %i% Z1
call lib getval %QUICK.ARRAY% %j% Z2
ECHO nachher
ECHO %QUICK.ARRAY%[%i%]=!Z1!
ECHO %QUICK.ARRAY%[%j%]=!Z2!
Rem Ausgabe gesamtes Array um zu sehen ob der Tausch funktioniert
Rem hat
FOR /L %%l IN (0, 1, 8 ) Do (
call lib getval %QUICK.ARRAY% %%l Z0
Echo !QUICK.ARRAY![%%l] !Z0!
)
PAUSE
endlocal
Rem die Indizes werden hoch bzw. runter gezählt
set /a i+=1
set /a j-=1
)
Rem falls der linke Index am rechten vorbei ist Abbruch
if %i% gtr %j% goto WEITER
goto :LINKS_NEXT
:WEITER
Rem Die Rekursion
IF %LOW.INDEX% LSS %j% call :qsort %QUICK.ARRAY% %LOW.INDEX% %j%
IF %i% LSS %HIGH.INDEX% call :qsort %j% %QUICK.ARRAY% %HIGH.INDEX%
Rem Zum Schluss Ausgabe des sortierten Arrays auf dem Bildschirm
setlocal enabledelayedexpansion
FOR /L %%l IN (0, 1, 8 ) Do (
call lib getval %QUICK.ARRAY% %%l Z0
Echo !QUICK.ARRAY![%%l] !Z0!
)
endlocal
ECHO FERTIG
goto :eof
Irgendwas fehlt mir - aber was? Das Pivotelement wird richtig gesetzt, die ersten Tauschaktionen laufen richtig. Aber dann wird nicht weitersortiert. Die Gotos habe ich eingebaut, nachdem ich verzweifelt versucht habe eine Endlosschleife zu konstruieren.
set /a j=0
for /L %%i in (0) do if not defined done (
set j+=1
echo Hallo %j%
if %j%==10 set done=break
)
geht nicht. der Job bleibt bei meinem CMD stehen. Bei
for /L %%i in (0,0,0) do if not defined done (
auch. Das hier geht auch nicht
set /a j=0
set /a x=1
for /L %%i in (0,1,%x%) do if not defined done (
set j+=1
set x+=1
echo Hallo %j%
if %j%==10 set done=break
)
Ich habe hier gelegentlich auch
for /L %i in (0,1,%x%) do
gesehen. Da bekomme ich auch eine Fehlermeldung. Die Zählvariable muss zwei Prozentzeichen haben und ich kann ihr auch keinen Wert zuweisen.
Also doch zwei Fragen.
1. Was ist bei meinem qsort falsch?
2. Gibt es eine andere Möglichkeit, eine Endlosschleife zu bauen?
Vielen Dank für Euer Interesse
LG
Leo
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 190354
Url: https://administrator.de/forum/mein-quicksort-funktioniert-nicht-bitte-um-hilfe-bei-der-fehlersuche-190354.html
Ausgedruckt am: 22.12.2024 um 12:12 Uhr
1 Kommentar
Hallo Leo,
dann möchte ich mich mal über Endlosschleifen auslassen.
Wie der Name schon sagt sind diese endlos, und Batch nimmt es hier sehr genau mit dem Endlos.
Mit einem goto oder exit /b kann zwar das weitere Ausführen der Scheife beendet werden, aber nicht die Schleife selbst!
Siehe ein kleines Beispiel
Wie wir sehen werden die Zahlen von 1 bis 5 ausgegeben, aber danach hängt die Batch.
Interessant wird es wenn man ECHO ON zu beginn schaltet, dann sieht man das der Abbruch leider die Schleife nicht abbricht, sie wird weiter aufgelöst aber nicht mehr ausgeführt.
Dies gilt übrigens nur für FOR /L, bei den anderen FOR Schleifen ist ein vorzeitiger Abbruch möglich.
Allerdings soll nicht verschwiegen werden, es ist auch mit FOR /L möglich, man braucht nur mit EXIT die Schleife zu beenden.
Dadruch sind aber etwas komplexere Konstrukte notwendig, wenn man danach noch weiterarbeiten möchte.
Dazu gibt es einen schönen Thread auf Dostips.com The ultimate while loop
Zu deiner ersten Frage: Was ist bei meinem qsort falsch?
Ja, das wüsste ich auch gerne, aber da wird wohl noch jemand eine gute Lösung finden ...
Gruß
jeb
dann möchte ich mich mal über Endlosschleifen auslassen.
Wie der Name schon sagt sind diese endlos, und Batch nimmt es hier sehr genau mit dem Endlos.
Mit einem goto oder exit /b kann zwar das weitere Ausführen der Scheife beendet werden, aber nicht die Schleife selbst!
Siehe ein kleines Beispiel
@echo off
setlocal EnableDelayedExpansion
set /a cnt=0
for /L %%n in (0) DO (
set /a cnt+=1
echo !cnt!
if !cnt!==5 goto :myExit
)
:myExit
Wie wir sehen werden die Zahlen von 1 bis 5 ausgegeben, aber danach hängt die Batch.
Interessant wird es wenn man ECHO ON zu beginn schaltet, dann sieht man das der Abbruch leider die Schleife nicht abbricht, sie wird weiter aufgelöst aber nicht mehr ausgeführt.
Dies gilt übrigens nur für FOR /L, bei den anderen FOR Schleifen ist ein vorzeitiger Abbruch möglich.
Allerdings soll nicht verschwiegen werden, es ist auch mit FOR /L möglich, man braucht nur mit EXIT die Schleife zu beenden.
Dadruch sind aber etwas komplexere Konstrukte notwendig, wenn man danach noch weiterarbeiten möchte.
Dazu gibt es einen schönen Thread auf Dostips.com The ultimate while loop
Zu deiner ersten Frage: Was ist bei meinem qsort falsch?
Ja, das wüsste ich auch gerne, aber da wird wohl noch jemand eine gute Lösung finden ...
Gruß
jeb