Datumalgorithmus
-
Hi,
ich hab einen Algorithmus geschrieben um zu prüfen ob ein Datum gültig ist, und verbessert wenn es falsch war. Ist etwas unübersichtlich, und ehrlich gesagt ich weiß garnicht ob er richtig funktioniert (hab ein paar Daten getestet hat funktioniert). Könnt ihr mir vielleicht irgendwelche Tipps geben, wie man ihn verbessern könnte (damit es überschaubarer und effizienter wird).// Das höchste Datum in einem Monat int monthdays_[] = { 31, // Januar 28, // Februar 31, // März 30, // April 31, // Mai 30, // Juni 31, // Juli 31, // August 30, // September 31, // Oktober 30, // November 31 }; // Dezember void Date::correctDate() { neustart: int result = checkDate(year_, month_, day_); switch( result ){ case 3: // Falscher Tag und Monat nochmal: /* Wird angesprungen, wenn der Tag falsch ist/war und falscher Monat berechnet wurde. */ case 2: // Falscher Monat year_ += int(month_ / 12); month_ = (12 + month_ % 12 ) % 12; if (result != 3) // Wenn nur Monat break; case 1: // Falscher Tag do{ int daysDiff = abs(day_); // Differenzen sind positiv if (daysDiff <= monthdays[month_]) break; // Jetzt ist der Tag richtig else { if (day_ > 0){ // Tage werden addiert day_ -= monthdays[month_]; ++month_; }else{ // und hier subtrahiert day_ += monthdays[month_]; --month_; } if ( (month_ < 0) || (month_ > 11) ){ result = 3; // Damit der Tag wieder angepasst werden kann goto nochmal; // Anspringen um den Monat zu korrigieren } } }while(true); } if (result != 0) goto neustart; }
-
Bah! Ein goto!!!!
Pack doch den Teil nach neustart in ne eigene Funktion, dann kannst du dir das häßliche goto sparen.mfg
Glamdring
-
In diesem Fall kann man das Goto lassen, auch wenn es nicht so schön ist.
Soweit sieht auch alles richtig aus.
-
In diesem Fall sehe ich das goto eher als Fehler im Konzept. Das kann man viel eleganter lösen. Das äußere goto-Konstrukt kann ohne große Änderungen durch eine do/while-Schleife ersetzt werden. Und mit einem goto in ein case zu springen ist mehr als Spaghetti. Das könnte man mit einer Rekursion vermeiden.
-
Sieht wie eine C Funktion aus.
In C++ würde man das anders lösen.
etwa so:
int res; while( (res=checkDate(...)) ) { if(res & WRONG_DAY) correctDay(); if(res & WRONG_MONTH) correctMonth(); }
und schon hätte man eine schönere Aufteilung. Wahrscheinlich geht es noch schöner - aber dieser Ansatz macht die Sache viel klarer.
-
Danke für die Beiträge, sorry dass ich nicht sofort antworten konnte, war paar Tage nicht zu Hause. Ich werde mich dann heute damit auseinandersetzen. Auf jeden Fall ist mir aufgefallen, dass der (gepostete) Algorithmus keine Schaltjahre beachtet.
Glamdrink schrieb:
Ein goto!!!!
Da sind zwei gotos
MaSTaH schrieb:
Und mit einem goto in ein case zu springen ist mehr als Spaghetti. Das könnte man mit einer Rekursion vermeiden.
Mir ist aufgefallen, dass der Sprung zum Label "nochmal:" garnicht notwendig ist, wenn man
... if ( (month_ < 0) || (month_ > 11) ) { break; } ...
schreibt. Dann wird zwar checkDate() durchgelaufen aber wenigstens gibt es keine Rekursion.
-
Was ist an Rekursion schlecht?
Ich für meinen Teil finde das sehr elegant.
-
Shade Of Mine schrieb:
Sieht wie eine C Funktion aus.
In C++ würde man das anders lösen.Was ist daran jetzt eigentlich mehr C++?
Ich denke ein guter C-Programmierer hätte das auch so geschrieben.
-
gelöscht
-
Hem, gibts dafür nicht ne richtige Formel?
-
Mis2com schrieb:
Was ist an Rekursion schlecht?
Ich für meinen Teil finde das sehr elegant.
Ich habe nicht behauptet dass eine Rekursion schlecht sei. Ist auf jeden Fall besser als break, aber was mir nicht gefällt ist, dass da der (unter Win98) stark begrenzte Heap-Speicher "belastet" wird. Bei dieser Funktion wird es vielleicht selten auftreten, aber die Möglichkeit ist gegeben.
-
bIce schrieb:
Ich habe nicht behauptet dass eine Rekursion schlecht sei. Ist auf jeden Fall besser als break, aber was mir nicht gefällt ist, dass da der (unter Win98) stark begrenzte Heap-Speicher "belastet" wird.
Ich finde Walnüsse sind besser als Äpfel!
break mit Rekursion zu vergleichen ist nicht euer Ernst oder?Außerdem wird durch Rekursion nicht der Heap belastet sondern der Stack. Und der sollte für gewöhnlich groß genug sein.
Aber nichtsdestotrotz ist es meistens sinnvoll nicht-rekursive Lösungen vorzuziehen, wenn sie nicht gerade deutlich komplexer sind.
MfG Jester