a2 Quelltext Dokumentation
This commit is contained in:
@ -4,72 +4,125 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
|
|
||||||
|
// der Makro "panicio" gibt einen Ein-/ Ausgabefehler aus und beendet das Programm mit einem Fehlercode.
|
||||||
#define panicio {\
|
#define panicio {\
|
||||||
perror(*filepath);\
|
perror(*filepath);\
|
||||||
return 1;\
|
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)
|
#define getNumber strtol(nextnumber + 1, &nextnumber, 10)
|
||||||
|
|
||||||
|
// Struktur, die ein Hotel darstellt.
|
||||||
struct hotel {
|
struct hotel {
|
||||||
uint_least16_t minutes;
|
uint_least16_t minutes;
|
||||||
uint_least8_t rating;
|
uint_least8_t rating;
|
||||||
};
|
};
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
|
// Schleife iteriert über die Argumente, die Dateipfade sind.
|
||||||
for(char **filepath = argv + 1; filepath - argv < argc; ++filepath) {
|
for(char **filepath = argv + 1; filepath - argv < argc; ++filepath) {
|
||||||
printf("%s:\n", *filepath);
|
|
||||||
uint_least16_t numberHotels, totalMinutes;
|
uint_least16_t numberHotels, totalMinutes;
|
||||||
struct hotel *hotels;
|
struct hotel *hotels;
|
||||||
|
printf("%s:\n", *filepath);
|
||||||
{
|
{
|
||||||
char *inputText;
|
char *inputText;
|
||||||
{
|
{
|
||||||
FILE *inputFile = fopen(*filepath, "rb");
|
FILE *inputFile = fopen(*filepath, "r"); // öffnet die Datei
|
||||||
if(inputFile == NULL) panicio;
|
if(inputFile == NULL) panicio; // gibt möglichen Fehler aus
|
||||||
bool success;
|
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);
|
inputText = acl_ReadTextFile(inputFile, &success);
|
||||||
if(!success) panicio;
|
if(!success) panicio;
|
||||||
fclose(inputFile);
|
fclose(inputFile); // schließt die Datei
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
char *nextnumber;
|
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;
|
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);
|
hotels = malloc(numberHotels * sizeof *hotels);
|
||||||
|
|
||||||
|
// jedem Hotel des Arrays werden die jeweiligen Werte zugewiesen
|
||||||
for(uint_least16_t i = 0; i < numberHotels; ++i) {
|
for(uint_least16_t i = 0; i < numberHotels; ++i) {
|
||||||
hotels[i].minutes = getNumber;
|
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 = 10 * getNumber;
|
||||||
hotels[i].rating += getNumber;
|
hotels[i].rating += getNumber;
|
||||||
}
|
}
|
||||||
hotels[numberHotels - 1] = (struct hotel){ .minutes = totalMinutes, .rating = 50};
|
|
||||||
}
|
}
|
||||||
free(inputText);
|
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};
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
struct hotel hotelRoute[4];
|
struct hotel hotelRoute[4]; // speichert die Hotels, an denen gehalten wird
|
||||||
uint_least8_t stoppedHotels;
|
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;
|
uint_least8_t rating = 50;
|
||||||
do {
|
do {
|
||||||
|
// Minuten die das letzte Hotel, bei dem angehalten wurde, vom Start entfertn ist
|
||||||
uint_least16_t lastHotelMinutes = 0;
|
uint_least16_t lastHotelMinutes = 0;
|
||||||
|
// Zeiger zum letzten Hotel, dessen Bewertung mindestens "rating" ist.
|
||||||
struct hotel *possibleStop = NULL;
|
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) {
|
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) {
|
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;
|
if(possibleStop == NULL || stoppedHotels >= 4) break;
|
||||||
|
// hängt das Hotel der Route an
|
||||||
hotelRoute[stoppedHotels] = *possibleStop;
|
hotelRoute[stoppedHotels] = *possibleStop;
|
||||||
lastHotelMinutes = possibleStop->minutes;
|
lastHotelMinutes = possibleStop->minutes;
|
||||||
|
// springt in der Schleife zurück zum Hotel, an dem gestoppt wurde
|
||||||
currentHotel = possibleStop;
|
currentHotel = possibleStop;
|
||||||
++stoppedHotels;
|
++stoppedHotels;
|
||||||
}
|
}
|
||||||
|
// Wenn die Bewertung hoch genug ist, kann gestoppt werden.
|
||||||
if(currentHotel->rating >= rating) possibleStop = currentHotel;
|
if(currentHotel->rating >= rating) possibleStop = currentHotel;
|
||||||
}
|
}
|
||||||
--rating;
|
--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));
|
} while(rating && (!stoppedHotels || totalMinutes - hotelRoute[stoppedHotels - 1].minutes > 360));
|
||||||
}
|
}
|
||||||
|
// gibt die Hotels der Route aus.
|
||||||
for(struct hotel *hotelPrint = hotelRoute; hotelPrint - hotelRoute < stoppedHotels; ++hotelPrint) {
|
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