ERLEDIGT
NEIN
NEIN
ANTWORTEN
0
0
ZUGRIFFE
229
229
EMPFEHLEN
-
So, erstmal ein wenig zur Erklaerung.
Mein Script (jodler.php) liest die Daten aus einer Text-Datei (jodler.txt) und gewichtet anschliessend die Strecken.
Dazu wird jede Strecke rueckwaerts durchlaufen. Dadurch spaere ich mir hier die ansonsten noetige Rekursion.
Dazu moechte ich sagen dass dies im Grunde die 7. Version der Gewichtung ist. Die erste Version, von der diese hier nun direkt abstammt, war aehnlich einfach, hatte aber ein paar Probleme mit der Gewichtung.
Die erste bis sechte Version hatten alle Probleme mit der Gewichtung. Dadurch konnte es, unter gewissen Umstaenden, dazu kommen dass der falsche Weg eingeschlagen wurde wenn der insgesamt laengste Weg im Zweig mit dem insgesamt niedrigeren Gewicht lag.
Das koennte passieren da immer die Gewichte der linken und rechten Zelle der naechsten Zeile addiert wurden.
Dieses Problem ist nun geloest dadurch dass immer nur das Gewicht des dominanten (hoeheres Gewicht, oder bei Gewichtgleichheit der Pfad mit dem laengeren Teilstueck)Zweiges weitergetragen wird.
Anschliessend erfolgt die Berechnung der laengsten Strecke.
Dies geschieht rekursiv indem schlichtweg der Gewichtung gefolgt wird. Bei Stellen mit gleichem Gewicht erhaelt der laengere Abschnitt Vorrang.
Die aus diesen Bearbeitungen gewonnenen Daten werden nun in einer Schleife durchlaufen um festzustellen welche Piste die laengste Abfahrt bietet.
Zu guter Letzt wird diese Piste ausgegeben (mit verschiedenen Methoden zur Ausgabe an den Browser oder in der Command-Line), inklusive Hervorhebung der laengsten Abfahrt.
Der letzte Abschnitt des Codes ist zum Debugging, hier werden alle Strecken mit Highlighting und Gewichtung ausgegeben. Hier fehlt die Verzweigung zwischen Web und CLI.
Uebrigens, damit weighcourse() sowohl das Gewicht in die Gewichtung des Teilabschnitte in das Array eintragen kann als auch das Ergebnis der Auswertung dieser Gewichtung der tracepath() zurueckgeben kann nutze ich eine Referenz.
Das Array wird weighcourse() als Referenz uebergeben. Dadurch wird dieses Array direkt bearbeitet und muss nicht zurueckgegeben werden. Der Rueckgabewert kann also fuer tracepath() genutzt werden.
So, jetzt aber mal zum Code. Mit Kommentaren, und im Grunde mehr als ich sonst mache...
Code php:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248
<?php error_reporting(E_ALL); /** * Diese Funktion "wiegt" den Kurs und all seine Abschnitte. * Anhand des Gesamtgewichts eines Abschnitts wird spaeter der zu nehmende Pfad bestimmt. * Die Abarbeitung von unten nach oben, also den Berg hinauf, macht Rekursion unnoetig. * * @param array $course * @return array */ function weighcourse(&$course) { //Durchlaufe die Piste von unten nach oben for ($row=count($course);$row>0;$row--) { //Durchlaufe die Zellen von links nach rechts for ($cell=0;$cell<count($course[$row-1]);$cell++) { //Initialisiere das Pfad-Gewicht mit der eigenen Laenge $course[$row-1][$cell]['weight']=$course[$row-1][$cell]['length']; //Falls es eine naechste Reihe gibt wird noch was am Gewicht geaendert if (isset($course[$row])) { //Ist das Gewicht der linken Zelle der naechsten Reihe kleiner als das der rechten Zelle addiere das Gewicht der rechten Zelle zum Gewicht der aktuellen Zelle hinzu if ($course[$row][$cell]['weight']<$course[$row][$cell+1]['weight']) { $course[$row-1][$cell]['weight']+=$course[$row][$cell+1]['weight']; } //Sind die Gewichte gleich wird anhand der Laenge des Teilstuecks entschieden elseif ($course[$row][$cell]['weight']==$course[$row][$cell+1]['weight']) { if ($course[$row-1][$cell]['length']<$course[$row][$cell+1]['length']) { $course[$row-1][$cell]['weight']+=$course[$row][$cell+1]['weight']; } else { $course[$row-1][$cell]['weight']+=$course[$row][$cell]['weight']; } } //Ist das Gewicht der linken Zelle der naechsten Reihe groesser als das der rechten Zelle addiere das Gewicht der linken Zelle zum Gewicht der aktuellen Zelle hinzu else { $course[$row-1][$cell]['weight']+=$course[$row][$cell]['weight']; } } } } return tracepath($course); } /** * Diese Funktion wertet den Kurs von oben nach unten aus. * Dabei wird der laengste Pfad berechnet und die entsprechend Indizes festgehalten. * Der Kurs wird anhand der zuvor in weighcourse() vorgenommenen Pfad-Gewichtung verfolgt. * Der Teil-Abschnitt mit dem hoechsten Gesamtgewicht hat Vorrang. * * @param array $course * @param int $row * @param int $cell * @return array */ function tracepath($course,$row=0,$cell=0) { //Setze die Laenge auf die Laenge des aktuellen Abschnitts $length=$course[$row][$cell]['length']; //Initialisiere den Pfad mit dem Index der aktuellen Zelle $path=array($cell); //Falls es eine naechste Zeile gibt wird diese ausgewertet und tracepath() nochmal aufgerufen if (isset($course[$row+1])) { //Ist das Gewicht der linken Zelle kleiner, oder, bei gleichem Gewicht die Laenge, wird als naechstes die rechte Zelle angesteuert if ((isset($course[$row+1][$cell+1])) && (($course[$row+1][$cell]['weight']<$course[$row+1][$cell+1]['weight']) || (($course[$row+1][$cell]['weight']==$course[$row+1][$cell+1]['weight']) && ($course[$row+1][$cell]['length']<$course[$row+1][$cell+1]['length'])))) { $nextcell=$cell+1; } //Ansonsten die linke... else { $nextcell=$cell; } //Rekursiver Aufruf von tracepath() zur weiteren Auswertung des Pfades $next=tracepath($course,$row+1,$nextcell); //Erhoehe die Laenge der Piste um die zurueckgegebene Laenge (welches die Laenge der Piste von der naechsten Zelle bis ganz unten ist) und haenge den zurueckgegebenen Pfad (auch von der naechsten Zelle bis ganz unten) an den aktuellen Pfad $length+=$next['length']; $path=array_merge($path,$next['path']); } //Rueckgabe der ermittelten Werte return array('length'=>$length,'path'=>$path); } //Daten einlesen $data=file_get_contents('jodler.txt'); //Zeilen trennen $lines=explode("\n",$data); //Erstellung und Fuellung des Pisten-Arrays $courses=array(); for ($line=0;$line<count($lines);$line++) { //Wenn die Zeile nicht leer ist und nicht mit einem numerischen Wert anfaengt dann ist es eine neue Piste if ((!empty($lines[$line])) && (!is_numeric(substr($lines[$line],0,1)))) { //Speicherung des Namens der Piste $name=$lines[$line]; //Speicherung der Hoehe der Piste if (isset($lines[$line+1])) { $line++; $height=$lines[$line]; } //Erstellung und Fuellung des Kurs-Arrays $course=array(); while ((isset($lines[$line+1])) && (is_numeric(substr($lines[$line+1],0,1)))) { $line++; $path=explode(' ',$lines[$line]); for ($sector=0;$sector<count($path);$sector++) { $path[$sector]=array('length'=>$path[$sector],'weight'=>false); } $course[]=$path; } //Nachdem sichergestellt wurde dass die Piste nicht leer ist wird sie ausgewertet und gespeichert if (!empty($course)) { //Pfad-Gewichtung und Berechnung des laengsten Pfades $longestpath=weighcourse($course); //Uebertragung der Daten in das Pisten-Array $courses[]=array('name'=>$name,'height'=>$height,'course'=>$course,'longestpath'=>$longestpath); } } } //Bestimmung der laengsten Piste $longestcourse=false; for ($x=0;$x<count($courses);$x++) { if (($longestcourse===false) || ($courses[$x]['longestpath']['length']>$longestcourse['longestpath']['length'])) { $longestcourse=$courses[$x]; } } //Ausgabe //HTML if (isset($_SERVER['REMOTE_ADDR'])) { //Name und Laenge der Piste echo '<div style="text-align:center; font-weight:bold;">'.$longestcourse['name'].' ('.$longestcourse['longestpath']['length'].')</div>'; //Ausgabe der Abschnitte der Piste for ($row=0;$row<count($longestcourse['course']);$row++) { echo '<div style="text-align:center;">'; for ($cell=0;$cell<count($longestcourse['course'][$row]);$cell++) { echo '<span style="margin-left:5px; margin-right:5px;'; //Highlighting falls der aktuelle Abschnitt Teil des laengsten Pfades ist if ($cell==$longestcourse['longestpath']['path'][$row]) { echo ' color:#ff0000;'; } echo '">'.$longestcourse['course'][$row][$cell]['length'].'</span>'; } echo '</div>'; } } //Text else { //Name und Laenge der Piste echo $longestcourse['name'].' ('.$longestcourse['longestpath']['length'].')'."\n"; //Die Laenge der Piste wird fuer die Einrueckungen bei der Ausgabe genutzt $height=$longestcourse['height']; //Ausgabe der Abschnitte der Piste for ($row=0;$row<count($longestcourse['course']);$row++) { //Einrueckung der Ausgabe for ($tab=0;$tab<$height-$row;$tab++) { echo "\t"; } for ($cell=0;$cell<count($longestcourse['course'][$row]);$cell++) { //Highlighting falls der aktuelle Abschnitt Teil des laengsten Pfades ist if ($cell==$longestcourse['longestpath']['path'][$row]) { echo '>>'; } echo $longestcourse['course'][$row][$cell]['length']; //Highlighting falls der aktuelle Abschnitt Teil des laengsten Pfades ist if ($cell==$longestcourse['longestpath']['path'][$row]) { echo '<<'; } echo "\t\t"; } echo "\n"; } } //Debug-Code der alle Strecken ausgibt //Nur HTML /*for ($x=0;$x<count($courses);$x++) { //Name und Laenge der Piste echo '<div style="text-align:center; font-weight:bold;">'.$courses[$x]['name'].' ('.$courses[$x]['longestpath']['length'].')</div>'; //Ausgabe der Abschnitte der Piste for ($row=0;$row<count($courses[$x]['course']);$row++) { echo '<div style="text-align:center;">'; for ($cell=0;$cell<count($courses[$x]['course'][$row]);$cell++) { echo '<span style="margin-left:5px; margin-right:5px;'; //Highlighting falls der aktuelle Abschnitt Teil des laengsten Pfades ist if ($cell==$courses[$x]['longestpath']['path'][$row]) { echo ' color:#ff0000;'; } echo '">'.$courses[$x]['course'][$row][$cell]['length'].'('.$courses[$x]['course'][$row][$cell]['weight'].')</span>'; } echo '</div>'; } }*/ ?>
Kurioses:- tracepath() hiess urspruenglich followthewhiterabbit().
- Versionen 3 bis 5 hatten pro Zelle 2 Gewichte, eines fuer den linken Pfad, eines fuer den rechten Pfad.
- Version 5 nutzte die kosmologische Konstante COSMOLOGIC um der Abschnittslaenge ein hoeheres Gewicht bei der Berechnung zu geben.
Diese Konstante musste aber sehr fein getunt werden und ist extem Abhaengig von den Eigenschaften der ausgewerteten Pisten.
PHP Class Collection - PHP-Klassen fuer PHP 5 (und Teilweise auch fuer PHP 4)
Updates: Catcher 1.1, FTPConnection 1.2, MultiSQL 1.1, RSS2 1.1, SMTPConnection 1.4
__________________
EasyLFS - Hintergrundinformationen, Installationsanleitung, Softwareliste und Download
EasyLFS Projektthread - Informationen, Status und Diskussion zu meiner Linux-Distribution
__________________
__________________Ich bin die Schildkroete, mein Sohn. Ich habe das Universum erschaffen, aber bitte mach mir daraus keinen Vorwurf; ich hatte Bauchschmerzen.
Zitat von Friedrich Nietzsche
Ähnliche Themen
-
[QUIZ#8] (Squares) Dennis Wronka (Fortran)
Von Dennis Wronka im Forum ArchivAntworten: 4Letzter Beitrag: 12.07.09, 06:34 -
[QUIZ#8] (Twister) Dennis Wronka (Python)
Von Dennis Wronka im Forum ArchivAntworten: 0Letzter Beitrag: 06.07.09, 18:46 -
[QUIZ#8] (GuessIt) Dennis Wronka (Java)
Von Dennis Wronka im Forum ArchivAntworten: 0Letzter Beitrag: 06.07.09, 11:10 -
[QUIZ#8] (FibFact) Dennis Wronka (VB.net)
Von Dennis Wronka im Forum ArchivAntworten: 0Letzter Beitrag: 06.07.09, 09:12 -
[QUIZ#8] (Greeter) Dennis Wronka (Ada)
Von Dennis Wronka im Forum ArchivAntworten: 0Letzter Beitrag: 05.07.09, 07:37





Login





