/****************************************/ /** EPROG Runde 1: Bsp. 1154 (schwer) **/ /** Programmierer: Michael Zöch **/ /** Matrikelnummer: 0305116 **/ /** E-mail: kongo@gmx.at **/ /** HP: www.8ung.at/kongo/index.html **/ /****************************************/ ---------------------------------------------------------------------------------------------------- |====================================== 0) Aufbau der Hilfe =======================================| ---------------------------------------------------------------------------------------------------- 0) Aufbau der Hilfe 1) Kurzbeschreibung 2) Spezifikation im txt Format 3) Detailbeschreibung 3.1) Konstanten und Variablen 3.2) Die Funktion main() 3.3) Die Funktion toKV() 4) Quellcode des Programms ohne Kommentare ---------------------------------------------------------------------------------------------------- |======================================= 1) Kurzbeschreibung ======================================| ---------------------------------------------------------------------------------------------------- Das Programm liest Strings ein (zb. "ABCD abcd AbCd aBcd...") die eine disjunktive Normalform darstellen. Dies tut das Programm bis es das Endzeichen "=" erhält und gibt daraufhin das passende Karnaugh-Veitch-Diagramm aus. (mehr Infos zu dem KV-Diagramm findest du im Buch von Schildt: "Grundlagen Informatik", 4. Ausgabe, Seite 177ff) Beispiel: Programm starten: $ java Disjnorm Eingabe: $ ABCD abcd AbCd aBcd = Ausgabe: 0001 0010 0100 0001 ---------------------------------------------------------------------------------------------------- |======================================== 2) Spezifikation ========================================| ---------------------------------------------------------------------------------------------------- (Konvertierung der HTML-Spezifikation) Kurzbeschreibung: Eine bool'sche Funktion in disjunktiver Normalform wird eingelesen; das entsprechende Karnaugh - Veitch - Diagramm wird ausgegeben. Aufgabenstellung: Lesen Sie eine bool'sche Funktion in der disjunktiven Normalform ein. Eine disjunktive Normalform besteht aus Disjunktionen von Vollkunjunktionen. Dazu wird folgende Notation verwendet: Es gibt genau vier Eingabevariablen, nämlich A, B, C und D. Diese werden immer in dieser Reihenfolge angegeben; es müssen immer alle vier Variablen vorkommen. Negierte Variablen werden klein geschrieben; es werden keine Operatoren angegeben. Jede Vollkunjunktion wird in einem eigenen String eingelesen. Am Ende des Ausdrucks wird ein "=" geschrieben. Beispiel: _ _ _ _ _ _ (AnBnCnD)v(AnBnCnD)v(AnBnCnD) wird durch "AbcD aBcD aBCd =" dargestellt. Für diesen Ausdruck soll Ihr Programm eine Kanraugh-Veitch-Tabelle mit folgender Variablenanordunung erstellen: c C C c a 0 0 0 0 b A 1 0 0 0 b A 0 0 0 0 B a 1 0 1 0 B D D d d Verwenden Sie die Zeichen "0" und "1" zum Beschreiben der logischen Zustände "falsch" und "wahr". Eingabedaten: Lesen Sie die Strings ein, die zusammen die disjunktive Normalform darstellen. Diese Strings müssen jeweils 4 Zeichen lang sein und die Buchstaben A, B, C und D in genau dieser Reihenfolge beinhalten (wobei es wie gesagt bedeutsam ist, ob die Buchstaben groß oder klein geschrieben werden). Es dürfen keine zwei gleichen Strings eingegeben werden. Das Ende des Datensatzes wird durch das Zeichen "=" markiert. Ausgabedaten: Bei korrekten Eingabedatensätzen soll Ihr Programm die vier Zeilen des Karnaugh-Veitch-Diagramms ausgeben, also vier Strings zu je vier Zeichen, wobei nur die Zeichen "0" und "1" vorkommen (der Rahmen der Tabelle 'c C C c' etc. in der oberen Darstellung dient nur zur Erläuterung und soll in der Ausgabe nicht aufscheinen). Trennen sie die vier Strings durch jeweils ein Leerzeichen und geben Sie am Ende einen Zeilenvorschub aus. Fehlerbehandlung: Sämtlichce Eingabedatensätze sind immer bis zum definierten Endezeichen einzulesen. Generell wird bei fehlerhaften Eingabedatensätzen nur eine einzige Fehlermeldung erzeugt, weitere Berechnungen werden nicht mehr durchgeführt. Sind die Datentypen bei allen Eingaben richtig, die eingegebenen Daten aber inhaltlich nicht korrekt oder erfüllen nicht die Bedingungen, so soll Ihr Programm "FALSCHE EINGABE", gefolgt von einem Zeilenvorschub ausgeben. Beispiele: Eingabedaten: AbCD ABCD aBCD AbCd = abCD abCd AbcD AbCD Abcd ABCD aBCD aBcd = Ausgabedaten: 0000 0110 0100 0100 0110 1101 0110 0101 ---------------------------------------------------------------------------------------------------- |====================================== 3) Detailbeschreibung =====================================| ---------------------------------------------------------------------------------------------------- ____________________________________________________________________________________________________ ___________________________________ 3.1) Konstanten und Variablen __________________________________ Das Programm definiert alle (Eingabe- und Ausgabe-) Strings als Konstanten, um so das Ändern von Ausdrücken zu vereinfachen und somit das Programm flexibler zu gestalten. Insgesamt gibt es nur eine Klassenvariable: static boolean kvdiag[][] = new boolean[4][4]; In dieser speichern wird das Karnaugh-Veitch-Diagramm. Dieses Diagramm ist eine grafische Darstellung von einem Algorithmus, um Funktionen zu vereinfachen. Das KV-Diagramm: c C C c a 0 0 0 0 b A 0 0 0 0 b A 0 0 0 0 B a 0 0 0 0 B D D d d Das KV-Diagramm ist eine Darstellung einer Funktion in disjunktiver Normalform mit vier Variablen. Jeder Eintrag entspricht dabei einer Vollkunjunktion. disjunktive Normalform: ABCD abcd AbCd aBcd ... Vollkunjunktion: 1. ABCD, 2. abcd, 3. AbCd, 4. aBcd, ... Das Programm liest wortweise diese Vollkunjunktionen ein und berechnet den dazugehörigen Eintrag in dem KV-Diagramm. Als Beispiel nehmen wir "abcd". Das Programm berechnet dabei aus "ab" die Zeile und aus "cd" die Spalte. "ab" wäre in unserem Fall die 0. Reihe und "cd" die 3. Spalte. Also setzen wir in unserem KV-Diagramm diesen Wert auf true. kvdiag[0][3] = true; Wenn das Programm das Zeichen "=" einliest bricht es ab und gibt, wenn kein Fehler aufgetreten ist, das KV-Diagramm aus. Die Reihen werden dabei nur durch ein Leerzeichen voneinander getrennt. Ausgabe (zu obigen Beispiel): 0001 0010 0100 0001 ____________________________________________________________________________________________________ _____________________________________ 3.2) Die Funktion main() _____________________________________ Die Funktion main() verwendet zwei Variablen. Erstens einen String für die Eingabe (input) und zweitens einen Boolean für die Fehlerbehandlung (err). Es liest solange Worte ein, bis das Endzeichen "=" eingegeben wird, auch wenn ein Fehler bereits aufgetreten ist. Dann prüft es ob der eingegebene String gleich "ABCD" ist. Dies prüft es aber ohne Unterscheidung der Groß/Kleinschreibung. Ist dies nicht der Fall, so wird err auf true gesetzt. Somit haben wir bis jetzt gewährleistet das die Eingabe richtig "formatiert" ist und können sie der Funktion toKV() übergeben. Diese berechnet das KV-Diagramm. Sollte diese Funktion false als Rückgabe liefern, ist ein Fehler aufgetreten und wir setzen err auf true. Gibt der Benutzer nach der Eingabe der Vollkunjunktionen ("ABCD") "=" ein, so bricht das Programm mit dem Einlesen ab und begibt sich zur Ausgabe. Sollte ein Fehler aufgetreten sein, gibt es "FALSCHE EINGABE" aus, waren alle Eingaben aber richtig, so gibt es das KV-Diagramm aus. Eine Reihe wird dabei als "0" und "1" ausgegeben. Zwischen den Reihen wird als Trennzeichen ein Leerzeichen eingefügt. Eine "1" steht dafür, dass die zu diesem Eintrag passende Vollkunjunktionen eingegeben wurde, eine "0", dass diese nicht eingegeben wurde. ____________________________________________________________________________________________________ _____________________________________ 3.3) Die Funktion toKV() _____________________________________ Wie schon gesagt, übergeben wir dieser Funktion die Eingabe, wenn kein Fehler aufgetreten ist. Als erstes berechnet die Funktion die für diesen Eintrag zugehörige Reihe und speichert diese in der Variable row. Dann berechnet es die Spalte und speichert diese in der Variable col. c C C c a 0 0 0 0 b A 0 0 0 0 b A 0 0 0 0 B a 0 0 0 0 B D D d d Die Berechnung der Reihe erfolgt mit Hilfe der ersten beiden Buchstaben "AB". Wie wir aus diesem Diagramm herauslesen können gibt es immer zwei mögliche Reihen für den Buchstaben "a" und zwei für "A". Kombiniert mit dem zweiten Buchstaben "b" oder "B" ergibt sich daraus nur eine mögliche Reihe. Ist zb. die Eingabe "aBcd" müssen wir die Reihe suchen wo "aB" vorkommt und die Spalte wo "cd" vorkommt. "ab" kommt dabei nur in der letzten Reihe vor (a 0 0 0 0 B) und "cd" ebenfalls nur in der letzten Spalte (c 0 0 0 0 d). Wo sich die beiden treffen, ist der zugehörige Eintrag und den setzen wir jetzt auf true: c C C c a 0 0 0 0 b A 0 0 0 0 b A 0 0 0 0 B a 0 0 0 1 B D D d d Sollte der Eintrag aber schon auf true gesetzt sein, so wurde diese Vollkunjunktion schon einmal eingegeben und wir liefern als Rückgabewert false. Damit signalisieren wir der Funktion main() das ein Fehler aufgetreten ist. ---------------------------------------------------------------------------------------------------- |========================================== 4) Quellcode ==========================================| ---------------------------------------------------------------------------------------------------- Für alle die keine Kommentare möchten, hier der Quellcode einmal ohne: import eprog.*; public class Disjnorm extends EprogIO { static final String IN_ENDZEICHEN = "="; static final String IN_UPPERCASE = "ABCD"; static final String OUT_1 = "1"; static final String OUT_0 = "0"; static final String OUT_TRENNZEICHEN = " "; static final String OUT_ERROR_MESSAGE = "FALSCHE EINGABE"; static boolean kvdiag[][] = new boolean[4][4]; static boolean toKV(String in) { int row=-1, col=-1; if (in.charAt(0) == IN_UPPERCASE.charAt(0)) { if (in.charAt(1) == IN_UPPERCASE.charAt(1)) row = 2; else row = 1; } else { if (in.charAt(1) == IN_UPPERCASE.charAt(1)) row = 3; else row = 0; } if (in.charAt(2) == IN_UPPERCASE.charAt(2)) { if (in.charAt(3) == IN_UPPERCASE.charAt(3)) col = 1; else col = 2; } else { if (in.charAt(3) == IN_UPPERCASE.charAt(3)) col = 0; else col = 3; } if (kvdiag[row][col] == true) return false; kvdiag[row][col] = true; return true; } public static void main(String[] args) { String input = ""; boolean err = false; do { input = readWord(); if (input.equals(IN_ENDZEICHEN)) break; if (err) continue; if (!input.equalsIgnoreCase(IN_UPPERCASE)) { err = true; continue; } if (toKV(input) == false) err = true; } while(true); if (err) { println(OUT_ERROR_MESSAGE); } else { for (int i = 0; i < 16; i++) { if (i != 0 && i%4 == 0) print(OUT_TRENNZEICHEN); print(kvdiag[i/4][i%4]==true ? OUT_1 : OUT_0); } println(); } } } ---------------------------------------------------------------------------------------------------- ------------------------------------------- END OF FILE -------------------------------------------- ----------------------------------------------------------------------------------------------------