/* * marvin.c - Anweisungen fuer Roboter Marvin zum Sortieren durch Umstapeln * * Blatt 2, Aufgabe 2, Grundlagen der Informatik 2 fuer E-Techniker * SoSe 2002, (c) Jan Bredereke * * Anweisungen fuer Roboter Marvin zum Sortieren durch Umstapeln. * Liest eine Datei ein, in der der Eingangsstapel beschrieben ist, * und gibt dann Anweisungen aus, wie Marvin diesen Stapel umstapeln * soll, um ihn sortiert ins Lager zu bringen. * * $Id: marvin.c,v 1.8 2002/06/27 08:48:16 brederek Exp $ */ #include #include "unboundedStack.h" /* * Druckt eine Umstapelanweisung fuer Marvin auf den Schirm. * * @param artikel Der umzustapelnde Artikel. * @param von Quellstapel. * @param nach Zielstapel. */ static void umstapelAnweisung( struct stackItem artikel, char *von, char *nach) { printf("%s mit Id %d und Volumen %d: von %s -> %s\n", artikel.artikeltyp, artikel.artikelId, artikel.artikelvolumen, von, nach); } /* * Druckt Anweisungen fuer Marvin auf den Schirm, wie er die * Stapel umschichten soll. Ziel ist, dass der Lagerstapel * schliesslich sortiert ist. * * @param eingangsStapel unsortierter Eingangsstapel. */ static void sortiereStapel(stackH eingangsStapel) { stackH hilfsStapel = createStack(); stackH lagerStapel = createStack(); int groesstesVolumen; struct stackItem aktArtikel; while (!isEmpty(eingangsStapel)) { groesstesVolumen = peek(eingangsStapel).artikelvolumen; /* * Umschichten des Eingangsstapels auf den Hilfsstapel mit * Merken des groessten Artikelvolumens. */ while (!isEmpty(eingangsStapel)) { aktArtikel = pop(eingangsStapel); push(hilfsStapel, aktArtikel); umstapelAnweisung(aktArtikel, "Eingangsstapel", "Hilfsstapel"); if (aktArtikel.artikelvolumen > groesstesVolumen) { groesstesVolumen = aktArtikel.artikelvolumen; } } /* * Umschichten des Hilfsstapels zurueck auf den Eingangsstapel, * nur der groesste Artikel kommt auf den Lagerstapel, * bzw. auch alle gleich großen Artikel. */ while (!isEmpty(hilfsStapel)) { aktArtikel = pop(hilfsStapel); if (aktArtikel.artikelvolumen == groesstesVolumen) { push(lagerStapel, aktArtikel); umstapelAnweisung(aktArtikel, "Hilfsstapel", "Lagerstapel"); } else { push(eingangsStapel, aktArtikel); umstapelAnweisung( aktArtikel, "Hilfsstapel", "Eingangsstapel"); } } } } /* * Liest den Eingangsstapel aus der angegebenen Datei ein. * In der ersten Zeile steht das unterste Element des Stapels, * und in der letzten Zeile das oberste Element. * * @param dateiName Name der Datei mit der Beschreibung des * Eingangsstapels. * @return unsortierter Eingangsstapel. */ static stackH leseStapelAusDatei(char *dateiName) { stackH stapel; FILE *datei; int feldNum; int zeile; struct stackItem item; stapel = createStack(); datei = fopen(dateiName, "r"); if(datei == NULL) { perror("Kann Datei nicht oeffnen"); exit(1); } zeile = 1; while(!feof(datei)) { feldNum = fscanf(datei, "%99s %d %d\n", &item.artikeltyp, &item.artikelId, &item.artikelvolumen); if((feldNum == EOF)) { break; } if(feldNum != 3) { fprintf(stderr, "Fehler: Zeile %d hat nicht drei korrekte Elemente!\n", zeile); exit(1); } if(item.artikelvolumen < 0) { fprintf(stderr, "Fehler: Zeile %d hat Artikelvolumen kleiner 0!\n", zeile); exit(1); } push(stapel, item); zeile++; } fclose(datei); return stapel; } /* Hauptprogramm, wird von der Kommandozeile aus aufgerufen. */ int main() { stackH stapel; /* der Eingangsstapel aus der Datei */ stapel = leseStapelAusDatei("eingang.txt"); sortiereStapel(stapel); }