a2 Quelltext Dokumentation
This commit is contained in:
@ -4,72 +4,125 @@
|
||||
#include <stdint.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
// der Makro "panicio" gibt einen Ein-/ Ausgabefehler aus und beendet das Programm mit einem Fehlercode.
|
||||
#define panicio {\
|
||||
perror(*filepath);\
|
||||
return 1;\
|
||||
}
|
||||
|
||||
/* Ein Makro, der die nächste Zahl der Eingabedatei zurückgibt.
|
||||
* In der Eingabedatei werden die Zahlen immer durch ein anderes Zeichen getrennt (Leerzeichen, newline-character, Punkt).
|
||||
* Da die Funktion "strtol" den Zeiger "nextnumber" immer auf das erste Zeichen nach der verarbeiteten Zahl zeigen lässt,
|
||||
* muss "nextnumber" um eins erhöht werden, um auf die nächste Zahl zu zeigen.*/
|
||||
#define getNumber strtol(nextnumber + 1, &nextnumber, 10)
|
||||
|
||||
// Struktur, die ein Hotel darstellt.
|
||||
struct hotel {
|
||||
uint_least16_t minutes;
|
||||
uint_least8_t rating;
|
||||
};
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
// Schleife iteriert über die Argumente, die Dateipfade sind.
|
||||
for(char **filepath = argv + 1; filepath - argv < argc; ++filepath) {
|
||||
printf("%s:\n", *filepath);
|
||||
uint_least16_t numberHotels, totalMinutes;
|
||||
struct hotel *hotels;
|
||||
printf("%s:\n", *filepath);
|
||||
{
|
||||
char *inputText;
|
||||
{
|
||||
FILE *inputFile = fopen(*filepath, "rb");
|
||||
if(inputFile == NULL) panicio;
|
||||
FILE *inputFile = fopen(*filepath, "r"); // öffnet die Datei
|
||||
if(inputFile == NULL) panicio; // gibt möglichen Fehler aus
|
||||
bool success;
|
||||
|
||||
/* Die Funktion "acl_ReadTextFile" liest die Datei aus und gibt den Inhalt als String zurück.
|
||||
* Die Variable "success" wird je nach Erfolg modifiziert.*/
|
||||
inputText = acl_ReadTextFile(inputFile, &success);
|
||||
if(!success) panicio;
|
||||
fclose(inputFile);
|
||||
fclose(inputFile); // schließt die Datei
|
||||
}
|
||||
{
|
||||
char *nextnumber;
|
||||
|
||||
/* Die Anzahl der Hotels muss noch den Makro "getNumber" verarbeitet werden,
|
||||
* da dieser vorraussetzt, das der Zeiger "nextnumber" bereits definiert ist.
|
||||
* Zudem wird noch Eins addiert, weil noch ein "Hotel" hinzugefügt wird,
|
||||
* das den Zielpunkt darstellt.*/
|
||||
numberHotels = strtol(inputText, &nextnumber, 10) + 1;
|
||||
totalMinutes = getNumber;
|
||||
totalMinutes = getNumber; // gesamte Fahrzeit
|
||||
|
||||
// belegt den Speicher für ein Array mit allen Hotels
|
||||
hotels = malloc(numberHotels * sizeof *hotels);
|
||||
|
||||
// jedem Hotel des Arrays werden die jeweiligen Werte zugewiesen
|
||||
for(uint_least16_t i = 0; i < numberHotels; ++i) {
|
||||
hotels[i].minutes = getNumber;
|
||||
|
||||
/* "strtol" verarbeitet nur ganze Zahlen. Deshalb werden die beiden Ziffern einzeln
|
||||
* verarbeitet. Da für die Bewertung ein Integer-Typ verwendet wird,
|
||||
* ist die resultierende Bewertung das zehnfache der Bewertung in der Eingabedatei.
|
||||
* Diese wird bei der Ausgabe wieder umgewandelt.*/
|
||||
hotels[i].rating = 10 * getNumber;
|
||||
hotels[i].rating += getNumber;
|
||||
}
|
||||
}
|
||||
free(inputText); // freigeben des Speichers der ausgelesenen Textdatei
|
||||
|
||||
/* fügt den Zielort als "Hotel" hinzu, da der Algorithmus ein Hotel erst dann berücksichtigt,
|
||||
* wenn das nächste Hotel außer Fahrtreichweite ist. Es gibt allerdings kein nächstes Hotel
|
||||
* vom letzten Hotel, weshalb das letzte Hotel als Haltepunkt nicht in Betracht gezogen wird.
|
||||
* Also wird der Zielort als "Hotel" hinmzugefügt, damit auch das letzte richtige Hotel
|
||||
* verwendet werden kann.*/
|
||||
hotels[numberHotels - 1] = (struct hotel){ .minutes = totalMinutes, .rating = 50};
|
||||
}
|
||||
free(inputText);
|
||||
}
|
||||
{
|
||||
struct hotel hotelRoute[4];
|
||||
uint_least8_t stoppedHotels;
|
||||
struct hotel hotelRoute[4]; // speichert die Hotels, an denen gehalten wird
|
||||
uint_least8_t stoppedHotels; // Anzahl der gemachten Stops
|
||||
|
||||
/* In der Schleife wird versucht eine Route mit der Bewertung von mindestens 50 zu bilden.
|
||||
* Wenn dies nicht erfolgrecih ist, wird es mit 49, 48, ... versucht bis eine Route gefunden wurde.*/
|
||||
{
|
||||
uint_least8_t rating = 50;
|
||||
do {
|
||||
// Minuten die das letzte Hotel, bei dem angehalten wurde, vom Start entfertn ist
|
||||
uint_least16_t lastHotelMinutes = 0;
|
||||
// Zeiger zum letzten Hotel, dessen Bewertung mindestens "rating" ist.
|
||||
struct hotel *possibleStop = NULL;
|
||||
stoppedHotels = 0;
|
||||
stoppedHotels = 0; // setzt Anzahl der Stops zurück
|
||||
|
||||
// iteriert über die Hotels
|
||||
for(struct hotel *currentHotel = hotels; currentHotel - hotels < numberHotels; ++currentHotel) {
|
||||
|
||||
/* Wenn das aktuelle Hotel mehr als 360 Minuten vom letzten Hotel entfernt ist,
|
||||
* muss das letzte Hotel verwendet werden an dem das Halten möglich war.*/
|
||||
if(currentHotel->minutes - lastHotelMinutes > 360) {
|
||||
/* Wenn das Halten nicht möglich ist oder bereits schon viermal
|
||||
* gehalten wurde, muss es mit einer niedrigeren Bewertung versucht
|
||||
* werden.*/
|
||||
if(possibleStop == NULL || stoppedHotels >= 4) break;
|
||||
// hängt das Hotel der Route an
|
||||
hotelRoute[stoppedHotels] = *possibleStop;
|
||||
lastHotelMinutes = possibleStop->minutes;
|
||||
// springt in der Schleife zurück zum Hotel, an dem gestoppt wurde
|
||||
currentHotel = possibleStop;
|
||||
++stoppedHotels;
|
||||
}
|
||||
// Wenn die Bewertung hoch genug ist, kann gestoppt werden.
|
||||
if(currentHotel->rating >= rating) possibleStop = currentHotel;
|
||||
}
|
||||
--rating;
|
||||
/* Schleife läuft solange "rating" mindestens Eins ist, da es keine niedrigeren Bewertungen
|
||||
* gibt. Wenn das letzte Hotel höchtens 360 Minuten vom Zielort entfernt ist, wurde
|
||||
* erfolgreich eine Route gefunden und die Schleife wird beendet. Allerdings wird dies nur
|
||||
* überprüft, wenn überhaupt an einem Hotel gehalten wurde, um den Zugriff auf nicht
|
||||
* definierten Speicher zu vermeiden.*/
|
||||
} while(rating && (!stoppedHotels || totalMinutes - hotelRoute[stoppedHotels - 1].minutes > 360));
|
||||
}
|
||||
// gibt die Hotels der Route aus.
|
||||
for(struct hotel *hotelPrint = hotelRoute; hotelPrint - hotelRoute < stoppedHotels; ++hotelPrint) {
|
||||
printf("Entfernung vom Start: %" PRIuLEAST16 " Minuten, Bewertung: %" PRIuLEAST8 "\n", hotelPrint->minutes, hotelPrint->rating);
|
||||
printf("Entfernung vom Start: %" PRIuLEAST16 " Minuten, Bewertung: %.1f\n", hotelPrint->minutes, (double)hotelPrint->rating / 10);
|
||||
}
|
||||
}
|
||||
free(hotels);
|
||||
free(hotels); // gibt den Speicher des Hotelarrays frei
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user