Programm zum Auswerten logischer Ausdrücke und Ausgabe von Wahrheitstafeln
-
Hallo,
werde ich mal machen. Mein Prof meinte noch als "Hinweis", ich solle mir einfach mal den Ausgangsvektor ansehen (also Spalte y) und dann anhand eines einfachen booleschen Ausdrucks überlegen, was genau da passiert (bei Eingabe des booleschen Ausdrucks). Er verwies desweiteren nochmals auf die bitweisen Operatoren, mit deren Hilfe man das Programm wohl mit wenig Code zusammenbauen kann.
Gruß
-
Ja, das wäre auch ein Ansatz - du betrachtest eine komplette Spalte der Wahrheitstabelle als Binärvektor und verrechnest ihn dann binär:
a=0x00FF;//0000000011111111 b=0x0F0F;//0000111100001111 c=0x3333;//0011001100110011 d=0x5555;//0101010101010101 erg = a&b&c | a&c&d | ~a&~b&d | ...;//das entspricht dem Ausdruck "y = abc + acd + .a.bd + ..." von oben
Anschließend mußt du erg nur noch in seine Bits zerlegen, um damit die Wertetabelle aufzubauen (zur Zerlegung folgst du der Grundstruktur aus '+').
-
Sorry, aber für mich hört sich das nicht gerade leicht an. Gibt es irgend ein Tutorial, welches sich mit dieser bitweisen Geschichte auseinandersetzt? Lese momentan "C von A bis Z". Dort wird das Thema nur seeeehr kurz angerissen. Ich wüsste garnicht wie man etwas in Bits zerlegt.
Gruß
-
vielleicht hilft euch das weiter: http://de.wikipedia.org/wiki/Karnaugh-Veitch-Diagramm
-
Ich weis zwar wie ein KV-Diagramm aufgebaut ist, jedoch ist mir nicht ganz klar wie ich dies auf mein Problem hier anwenden soll.
-
JackBeauregard schrieb:
Ich weis zwar wie ein KV-Diagramm aufgebaut ist, jedoch ist mir nicht ganz klar wie ich dies auf mein Problem hier anwenden soll.
ich bin drauf gekommen durch den letzten beitrag von CStoll. vielleicht kann man davon irgendwas ausschlachten für dein programm. allein schon die anordnung von 4 variablen in einer quadratischen matrix ist vielleicht eine überlegung wert...
-
Mal eine Prinziplösung:
const unsigned short inputs[]={0x00FF,0x0F0F,0x3333,0x5555};//Input-Spalten der Wertetabelle unsigned short klausel(char* data) { int res=0xFFFF; //werte eine einzelne Klausel 'abd' oder 'a.b' aus //dazu kannst du für jedes Zeichen bis zum '+'/'\0' den passenden input[] //(oder seine Negation) zu res dazu-ANDen return res; } unsigned short formel(char* data) { int res=0; //werte die komplette Formel aus //hier zerlegst du die Eingabe an den +-Zeichen und gibst jeden Teil an klausel() weiter //die jeweiligen Ergebnisse werden mit res ver-ORt return res; } #define bit(v,b) (v&(1<<b)!=0) int main() { char text[100]; //Formel in 'text' eingeben unsigned short val = formel(text); printf("a b c d | res\n"); for(int i=0;i<16;++i) printf("%i %i %i %i | %i\n",bit(input[0],i),bit(input[1],i),bit(input[2],i),bit(input[3],i),bit(val,i));
Eventuell solltest du dir mal die Funktionsweise der Bit-Operatoren ansehen.
-
Hallo,
bin erst heute wieder dazu gekommen etwas für das Programm zu tun. Es stellt sich nunmehr folgende Frage: Mein Prof will, dass die Konjunktion OHNE Operator durchgeführt wird, d.h. y = abc, was soviel wie "a und b und c" bedeuten soll. Es fällt mir schwer dies in Quelltext zu fassen, d.h. das Programm dazu zu bringen den Ausdruck abc als "a und b und c" zu erkennen. Vielleicht denke ich auch nur sehr umständlich. Bin über jeden Hinweis dankbar.
Gruß
-
Du gehst in einer Schleife über den Teilstring dieser Klausel und wählst anhand des jeweiligen Buchstaben aus, welche Eingabevariable du draufrechnest:
unsigned short klausel(char* data) { unsigned short res=0xFFFF; for(;strchr("abcd.",*data)!=NULL;++data)//alle Zeichen außer a bis d und '.' brechen die Schleife ab { if(isalpha(*data)//Buchstabe a bis d res&=inputs[*data-'a']; else//kein Buchstabe, also '.' { ++data; if(*data<'a' || *data>'d') error("falsche Eingabe"); res&= ~inputs[*data-'a']; } } return res; }
-
Hallo,
eins vorab, die Funktionen sind noch nicht wirklich fertig, d.h. bspw writelist ist noch garnicht auf die Variablenanzahl angepasst usw.. Habe bislang folgendes zusammengebaut:
#include <stdio.h> #define MAXFLEN 100 #define bit(v,b) ((v&(1<<b)) != 0) . . . int func(char funktion[MAXFLEN]) { int i; int c; int banz; do { printf("\nBitte booleschen Ausdruck eingeben:\n"); printf("Y = "); fgets(funktion, MAXFLEN, stdin); banz = pruef(funktion); } while(banz == 0); printf("Y = %s\n", funktion); return banz; } int menue(void) { printf("1 = Eingabe der logischen Funktion\n" "2 = Ausgabe der Wahrheitstafel\n" "0 = Programmende\n\n"); return readint("Auswahl: ", 0, 2); } int readint(char msg[], int lower, int upper) { int zahl, n; do { printf("%s", msg); n = scanf("%d", &zahl); while (getchar() != '\n'); if (n != 1) printf("\nBitte nur Zahlen eingeben!\n\n"); else if (zahl < lower) { printf("\nUngueltiger Bereich!\n\n", lower); n = 0; } else if (zahl > upper) { printf("\nUngueltiger Bereich!\n\n", upper); n = 0; } } while (n != 1); return zahl; } int writelist(void) { const unsigned short a = 0x00FF; const unsigned short b = 0x0F0F; const unsigned short c = 0x3333; const unsigned short d = 0x5555; int i; printf("\na b c d | y\n"); printf("--------|--\n"); for(i = 15; i >= 0; i--) printf("%i %i %i %i | %i\n", bit(a,i), bit(b,i), bit(c,i), bit(d,i)); } int main() { int i; int auswahl; char funktion[MAXFLEN]; printf("Boolesche Ausdruecke und Wahrheitstafeln\n" "----------------------------------------\n\n"); do { auswahl = menue(); switch (auswahl) { /*Auswahl des Menuepunktes 1*/ case 1: func(funktion); break; /*Auswahl des Menuepunktes 2*/ case 2: writelist(); break; /*Auswahl des Menuepunktes 0*/ case 0: printf("\nProgrammende!"); break; } } while(auswahl = 0); return 0; } int pruef(char funktion[MAXFLEN]) { int a = 0; int b = 0; int c = 0; int d = 0; int punkt = 0; int oder = 0; int i; if(funktion[0] == '+'){ printf("Zu Beginn des Ausdrucks kein Oder!"); return 0; } for(i = 0; i < MAXFLEN; i++){ if(funktion[i] == 'a'){ a = 1; punkt = 0; oder = 0; } else if(funktion[i] == 'b'){ b = 1; punkt = 0; oder = 0; } else if(funktion[i] == 'c'){ c = 1; punkt = 0; oder = 0; } else if(funktion[i] == 'd'){ d = 1; punkt = 0; oder = 0; } else if(funktion[i] == '.'){ if(punkt == 1){ printf("Syntaxfehler: Doppelte Negation an Stelle %i\n", i); return 0; } else { punkt = 1; } } else if(funktion[i] == '+'){ if(punkt == 1){ printf("Syntaxfehler: Negation des Oder-Symbols an Stelle %i\n", i); return 0; } if(oder == 0){ oder = 1; }else{ printf("Syntaxfehler: Zwei Oder-Symbole nacheinander an Stelle %i" "\n", i); return 0; } } else{ if(funktion[i] == ' '){ } else if(funktion[i] == '\n') { } else if(funktion[i] == '\0') { if(punkt == 1 | oder == 1) { printf("Unzulaessiges Symbol am Ende des Ausdrucks!\n"); return 0; } i = MAXFLEN; } else { printf("Syntaxfehler: Unzulaessiges Symbol(%c) an Stelle %i\n", funktion[i], i+1); return 0; } } } if((a+b+c+d) < 2){ printf("Bitte mindestens 2 Variablen benutzen!\n"); return 0; } if(((a+b+c+d) == 3) && (d == 1)){ printf("Bitte die Variablen nach Alphabetischer Reihenfolge waehlen!\n"); return 0; } if(((a+b+c+d) == 2) && ((c == 1)|(d == 1))){ printf("Bitte die Variablen nach Alphabetischer Reihenfolge waehlen!\n"); return 0; } return (a+b+c+d); }
Das Ganze soll so ablaufen, dass nach der Eingabe des log. Ausdrucks (Menüpunkt 1) ins Auswahlmenue zurückgesprungen werden soll und der Benutzer die Möglichkeit bekommen soll Menüpunkt 2 auszuwählen um so eine Wahrheitstabelle ausgegeben zu bekommen. Genauso soll nach der Ausgabe der Tabelle ins Auswahlmenue zurück gesprungen werden.
Wie kann dies realisiert werden? Ans Ende der Funktion ein main(); hängen wäre ja nicht wirklich gut ;). Wichtig ist ja hierbei, dass der eingegebene Ausdruck gespeichert wird damit er dann über die Wahrheitstafel ausgegeben werden kann.
Ich hoffe, dass ihr versteht was ich meine.
Achja, eine generelle Meinung/Kritik zum Quellcode wäre sehr willkommen. Da ich mich nicht unbedingt an das gehalten habe was CStoll mir vorgeschlagen hat, ist diese sicherlich angebracht ;).
Gruß
-
JackBeauregard schrieb:
Das Ganze soll so ablaufen, dass nach der Eingabe des log. Ausdrucks (Menüpunkt 1) ins Auswahlmenue zurückgesprungen werden soll und der Benutzer die Möglichkeit bekommen soll Menüpunkt 2 auszuwählen um so eine Wahrheitstabelle ausgegeben zu bekommen. Genauso soll nach der Ausgabe der Tabelle ins Auswahlmenue zurück gesprungen werden.
Wie kann dies realisiert werden? Ans Ende der Funktion ein main(); hängen wäre ja nicht wirklich gut ;). Wichtig ist ja hierbei, dass der eingegebene Ausdruck gespeichert wird damit er dann über die Wahrheitstafel ausgegeben werden kann.
Keiner nen Tipp? Habe es schon mit verschiedenen Schleifenkonstrukten versucht, aber bislang erfolglos.