CString in Bool'sche Algebra "umwandeln"

Wenn ich Dich richtig verstanden habe, dann sind die Zahlen in Deinem Beispiel nicht die eigentlichen Werte, sondern die Indices eines Arrays, in dem die Werte stehen. Die Funktion 'WertVon(...)' würde also in diesem Fall den Wert zurückgeben, der an der angegebenen Stelle im Array steht.

Wenn du alle möglichen Kombinationen logischer Operatoren mit 7 Operanden durchtesten willst, mußt Du erstmal alle Kombinationen zusammenstellen. Dann rufst du einfach für alle Kombinationen die 'Evaluate(...)' Funktion auf und, wenn das Ergebnis 0 ist, schreibst Du die Kombination in eine Datei.

Du solltest allerdings beachten, daß es bei 7 Operanden und 2 verschiedenen Operatoren nach meiner Rechnung 322560 Möglichkeiten bestehen. Und da gibt es noch keine Klammern und keine Negation. Aber die Kombinationen kannst Du ja auch mit einem Algorithmus erzeugen.
 
Ja genau..... die Zahlen in meiner Beispiels-Formel sind keine Werte, sondern Indizes !
Als ich mit dem "Projekt" angefangen habe, hätte ich nicht gedacht, daß das so heftig wird ! :(

Das Problem ist halt, daß ich alle Kombinationen brauchen würde ! Ursprünglich (bevor ich auf diese ganzen Hindernisse gestoßen bin) hatte ich mir das ja ungefähr so vorgestellt:

Ich zerpflücke die Formel in ihre "Terme".... sprich '0&1&2', '3&4' und '5'. Dann setze ich für die einzelnen Bausteine Werte ein; habe ich also drei Bausteine in einem Term, durchlaufe ich mit einer Schleife ein zweidimensionales Array mit folgender Form:
Code:
BOOL drei[8][3] = {{0,0,0},
		   {1,0,0},
		   {0,1,0},
		   {1,1,0},
		   {0,0,1},
		   {1,0,1},
		   {0,1,1},
		   {1,1,1}};
Die Spalten sind die Bausteine und die Zeilen sind die entsprechenden Möglichkeiten... so werden alle Kombinationen durchgespielt. Und dann müsste ich diese Ergebnisse wieder zusammenbringen.
Diese eine Formel festcodiert auszuwerten würde ich ja hinkriegen, aber ein allgemeingültiges Programm, daß jede x-beliebige Formel auswerten kann, ist total schwer ! Macht man das dann doch besser mit Hilfe eines Binärbaumes ?

Ich bezweifle, daß ich das jemals hinbekomme !! :(
 
Tut mir leid, aber ich kapiere noch nicht so ganz, was Du machen möchtest.
Was hast du als Ausgangsterm und was willst Du damit genau machen?
 
Erstmal Danke für deine Geduld..... ich versuche es nochmal zu erklären....

Also:
Ein Ausgangsterm wird vom Anwender vorgegeben... es handelt sich um eine beliebige logische Verknüpfung... also zum Beispiel:
"E1 = ((A1 & B3 & A2) | (X5 & B2)) & F" (was diese Operanden aussagen ist völlig egal).
Ich ersetze die Operanden durch Zahlen, so daß ich sie leichter zuordnen kann (und ich dann auch mit Indizes arbeiten kann).... daraus ergibt sich dann mein Formel-Beispiel "((0 & 1 & 2) | (3 & 4) & 5"

Jetzt möchte ich, wie bei einer Wahrheitstabelle, alle Möglichkeiten durchspielen.... und möchte dann sehen, für welche Werte der einzelnen Operanden E1 gleich NULL ist.
Ich gehe also die Wertetabelle Zeile für Zeile durch...

0 0 0 0 0 0
1 0 0 0 0 0
0 1 0 0 0 0
1 1 0 0 0 0
0 0 1 0 0 0
1 0 1 0 0 0
......

Und jede Bitkombination (Zeile), die E1 = 0 ergibt, will ich dann in eine Datei schreiben.

War das jetzt vielleicht ein bißchen verständlicher ?
 
Ich glaube, jetzt habe ich's kapiert.

Um das mit der oben beschriebenen rekursiven Methode zu lösen, mußt du für jede Kombination von Operanden den Algorithmus durchlaufen und immer die aktuellen Werte aus Deinem Array holen.

Es gibt auch noch eine andere Möglichkeit, bei der Du immer beide möglichen Werte eines Operanden betrachtest und Dir die Ergebnisse von Teilausdrücken merkst, aber das ist dann aufwändiger.

EDIT:
Mit einem Baum wäre das mögliocherweise schneller, da Du den Baum dann nur einmal aufbauen mußt und nur noch die Operanden änderst.
 
Hallo,

ich hatte vor einiger Zeit mal einen Parser geschrieben der einen mathematischen
Term auswertet.
Den jetzt auf deinen Anwendungsfall umzuschreiben war nicht so der Aufwand :)

Code:
#include <iostream>
#include <sstream>
#include <vector>
#include <string>

using namespace std;

class ParserException{
	public:
		virtual const string& message() = 0;
		virtual ~ParserException(){}
};

class BadSyntaxException : public ParserException{
	private:
		string expected;
		string got;
		string mess;
		int charPosition;
	public: 
		BadSyntaxException(const string& expected, const string& got, int position) :
			expected(expected), got(got), charPosition(position){}

		virtual ~BadSyntaxException(){}

		virtual const string& message(){
			ostringstream os;
			os << "Syntax error at character position " << charPosition
				<< ": expected '" << expected << "' got '" << got << "'";
			mess = os.str();
			return mess;
		}
};

class ParenthesisOutOfBalanceException : public BadSyntaxException{
	private:
		int numberOfForgottenBrackets;
		string mess;
	public:
		ParenthesisOutOfBalanceException(const string& expected, const string& got, int number, int position) :
			BadSyntaxException(expected, got, position), numberOfForgottenBrackets(number){}

		const string& message() {
			ostringstream os;
			os << BadSyntaxException::message() << ", you need to close "
				<< numberOfForgottenBrackets << " brackets!";
			mess = os.str();
			return mess;
		}
};

/**
 * the data structure which represents the operator tree
 */
template <typename T>class OpTree{
	private:
		OpTree* right;
		OpTree* left;
		string value;
		static vector<T> value_table;

	public:
		OpTree(const string& value) : right(NULL), left(NULL), value(value){}

		~OpTree(){
			if(right != NULL)
				delete right;
			if(left != NULL)
				delete left;
			right = NULL;
			left = NULL;
		}

		void setLeftSon(OpTree* left){
			this->left = left;
		}

		void setRightSon(OpTree* right){
			this->right = right;
		}

		void setValues(const vector<T>& table){
			value_table = table;
		}
		/**
		 * generates the result from the created OpTree
		 * traverses the tree in postorder
		 */
		T getResult(){
			istringstream is(value);
			int index;
			is >> index;
			if(left == NULL && right == NULL){
				return value_table[index];
			}
			else{
				if(value == "|")
					return left->getResult() || right->getResult();
				else
					return left->getResult() && right->getResult();
			}
		}
};

template <typename T> vector<T> OpTree<T>::value_table;

/**
 * creates a syntax tree from the following grammer:
 * expressiom ::= term {'|' term}*
 * term ::= factor {'&' factor}*
 * factor ::= T | '(' expression ')'
 */
template <typename T>class TermParser{
	private:
		vector<string> to_parse;
		OpTree<T>* root;
		int numberOfBrackets;
		int charPosition;

		/**
		 * creates the non terminal expression according to the grammar rules
		 */
		void exp() throw (BadSyntaxException){
			term();
			while(to_parse[0] == "|"){
				OpTree<T>* oldRoot = root;
				root = new OpTree<T>(to_parse[0]);
				root->setLeftSon(oldRoot);
				OpTree<T>* oldRoot2 = root;
				to_parse.erase(to_parse.begin());
				charPosition += 2;
				term();
				oldRoot2->setRightSon(root);
				root = oldRoot2;
			}
		}

		/**
		 * creates the non terminal term according to the grammar rules
		 */
		void term(){
			factor();
			while(to_parse[0] == "&"){
				OpTree<T>* oldRoot = root;
				root = new OpTree<T>(to_parse[0]);
				root->setLeftSon(oldRoot);
				to_parse.erase(to_parse.begin());
				charPosition+=2;
				OpTree<T>* oldRoot2 = root;
				factor();
				oldRoot2->setRightSon(root);
				root = oldRoot2;
			}
		}

		/**
		 * creates the non terminal factor according to the grammar rules
		 */
		void factor() throw (ParserException){
			if(to_parse[0] == "("){
				numberOfBrackets++;
				to_parse.erase(to_parse.begin());
				charPosition+=2;
				exp();
				if(to_parse[0] != ")")
					throw ParenthesisOutOfBalanceException(")", "missing parenthesis",
							numberOfBrackets, charPosition);
				numberOfBrackets--;
				to_parse.erase(to_parse.begin());
			}
			else{
				for(unsigned int i = 0; i < to_parse[0].size(); i++){
					if((to_parse[0])[i] > '9' || (to_parse[0])[i] < '0')
						throw BadSyntaxException("[0-9]+", to_parse[0], charPosition);
				}
				root = new OpTree<T>(to_parse[0]);
				to_parse.erase(to_parse.begin());
			}
			charPosition+=2;
		}

	public:
		TermParser() :
			root(NULL), numberOfBrackets(0), charPosition(0){}

		~TermParser(){
			if(root != NULL)
				delete root;
		}

		/**
		 * parses the given expression for the given grammar and computes the operator tree
		 * note: every expression string must be terminated by ;
		 * note2: the syntaxes must be delimited by a space  character (ascii 0x20)
		 */

		void parse(char* expression) throw (ParserException){
			char* token = strtok(expression, " ");
			to_parse.push_back(token);
			while((token = strtok(NULL, " ")) != NULL)
				to_parse.push_back(token);
			exp();
			if(to_parse.size() == 0 || to_parse[0] != ";"){
				throw BadSyntaxException(";", "unknown eof sequence", charPosition);
			}
		}

		/**
		 * returns the result of the expression after it is parsed
		 */
		T getResult(){
			return root->getResult();
		}
		void setValues(const vector<T>& table){
			root->setValues(table);
		}
};

int main(){
	//every expression must be terminated by ;
	//as delimiter the ' '(whitespace) is used
	//e.g. :
	char expression[] = "( 0 & 1 & 2 ) | ( 3 & 4  & 5 ) ;";
	vector<vector<bool> > truthTable;
	//equation1 = (true & false & true) | (true & false & true)
	truthTable.push_back(vector<bool>());
	truthTable[0].push_back(true);
	truthTable[0].push_back(false);
	truthTable[0].push_back(true);
	truthTable[0].push_back(true);
	truthTable[0].push_back(false);
	truthTable[0].push_back(true);
	//equation2 = (true & false & false) | (true & true & true)
	truthTable.push_back(vector<bool>());
	truthTable[1].push_back(true);
	truthTable[1].push_back(false);
	truthTable[1].push_back(false);
	truthTable[1].push_back(true);
	truthTable[1].push_back(true);
	truthTable[1].push_back(true);

	TermParser<bool> p;
	try{
		p.parse(expression);
		for(unsigned int i = 0; i < truthTable.size(); i++){
			p.setValues(truthTable[i]);
			cout << "Equation" << i + 1 << " = " << p.getResult() << endl;
		}
	}catch(ParserException& e){
		cout << "Exception" << endl;
		cout << e.message() << endl;
	}
}

Irgendwelche Garantien auf Fehlerfreiheit kann ich nat. nicht gewährleisten :)

P.S. siehe auch http://www.tutorials.de/forum/c-c/219171-string-int.html?highlight=Parser

Gruß,
RedWing
 
Zuletzt bearbeitet:

Neue Beiträge

Zurück