Expression Bäume


julia123

Erfahrenes Mitglied
#1
hi nochmal,

wiess nicht wieso aber mein Theman wurde gelöst. Denke wegen Doppelpost,sorry :( )

Im Kommentar sind meine Problemstellen hinterlägt.



Java:
import java.util.LinkedList;
import java.util.List;

public class Expressions {
	private Expressions() {
	}

	// Ausdrucksbaeume
	public interface Expression {
		int evaluate();
	}

	public static abstract class ComplexExpression implements Expression {
		private Expression x;//
		private Expression y;

		public ComplexExpression(Expression x, Expression y) {

			this.x = x;
			this.y = y;

		}

		protected Expression getx() {

			return x;
		}

		protected Expression gety() {

			return y;
		}
	}

	public static class Const implements Expression {

		private int y;

		public Const(int y) {

			this.y = y;

		}

		@Override
		public int evaluate() {

			return y;
		}

	}

	public static class Add extends ComplexExpression {

		public Add(Expression x, Expression y) {

			super(x, y);

		}

		@Override
		public int evaluate() {

			return getx().evaluate() + gety().evaluate();
		}

	}

	public static class Sub extends ComplexExpression {

		public Sub(Expression x, Expression y) {
			super(x, y);
		}

		@Override
		public int evaluate() {

			return getx().evaluate() - gety().evaluate();
		}
	}

	public static class Div extends ComplexExpression {

		public Div(Expression x, Expression y) {

			super(x, y);// höhers Objekt zugreifen

		}

		@Override
		public int evaluate() {
			if (getx().evaluate() == 0) {
				System.out.println("division durch 0");
			}

			return getx().evaluate() / gety().evaluate();
		}

	}

	public static class Mult extends ComplexExpression {

		public Mult(Expression x, Expression y) {
			super(x, y);
		}

		@Override
		public int evaluate() {

			return getx().evaluate() * gety().evaluate();
		}
	}

	private static class ToPostfix {
		private int pos = 0;
		private List<Expression> result = new LinkedList<>();

		public ToPostfix(String expression) {
			parseToPostfix(expression);
		}

		public List<Expression> get() {
			return result;
		}

		// ein paar keine Anpassungen hier
		private void parseToPostfix(String expr) {
			if (istZiffer(expr.charAt(pos))) {
				result.add(new Const(expr.charAt(pos) - '0'));// das ist doch
																// ein Integer
																// wieso hier
																// char?
				++pos;

				// zB. (2+2)
			} else if (expr.charAt(pos) == '(') {
				char op;
				++pos;
				parseToPostfix(expr);
				//hier mein Problem
				// ....
				// ....
				op = expr.charAt(pos);
				++pos;
				parseToPostfix(expr);// rekusion ziffer zuerst 2,6

				
				
				++pos; // ’)’

			} else {
			}
		}

		private static boolean istZiffer(char c) {
			return (c >= '0' && c <= '9');
		}
	}

	// Liefert eine PostfixDarstellung des Ausdrucks
	public static List<Expression> toPostfix(String expression) {
		return new ToPostfix(expression).get();
	}

	public static void main(String[] agrs) {
		System.out.println(toPostfix("((2+6)/(3*4)))")); // -->> [2, 6, +, 3, 4,
															// *, /]
		System.out.println("((2+6)/(3*4)))");
	}
 
#2
Hi

Java:
result.add(new Const(expr.charAt(pos) - '0'));// das ist doch
                                                                // ein Integer
                                                                // wieso hier
                                                                // char?
Das ist kein Integer.
expr.charAt(pos) ist, wie der Name sagt, der Buchstabe an der Stelle pos (als char),
und '0' ist das Ascii-Zeichen der Ziffer 0, auch ein char, Zahlenwert 48.

Sonst sehe ich da keine Frage.

Dein letztes Thema würde gelöscht, weil du selbst darum gebeten hast.
 

julia123

Erfahrenes Mitglied
#3
Aber bei Const() im Konstruktor wird ein int erwartet. Und was soll dass - bei -'0'. das hab ich nicht verstanden.

Und dann noch die Frage ich versteh nicht wie ich es machen soll das einfach nur z.b '+' dargestellt wird.

Ich hab hab jetzt an sowas gedacht das z.b. jetzt der String an dieser Stelle wo ich ein '+' erwarte mit Expression add vergleiche. Und dieser dann in die Liste eingefühgt wird.

Ich hoffe ihr könnt mich verstehen :(
 
#4
Das - beim '0' ist "Minus", nichts anderes. Grundrechenarten.
Und wenn da ein char als Variable auch nur eine ganzzahlige Nummer ist
(bei der man für jede Zahl einen Buchstaben etc. dazudenken kann)
kann man es ganz normal als Integer übergeben und damit Rechnen.

Ein String (im Inneren ein Array von char) ist nichts anderes als ein Array von Nummern.
Das, was die Buchstaben aumacht, sind Funktionen wie System.out.println,
die pro Nummer ein bestimmtes "Bild" (das eben ausschaut wie ein Buchstabe) ausgeben.

Den Rest hab ich nicht verstanden.
Fang vielleicht mal damit an, was du am Ende haben willst (gesamt).
 

HonniCilest

Erfahrenes Mitglied
#5
Aber bei Const() im Konstruktor wird ein int erwartet. Und was soll dass - bei -'0'. das hab ich nicht verstanden.
Wie sheel schon erwähnt hat das Zeichen '0' den Zahlenwert 48 (siehe ASCII-Tabelle). Alle anderen Ziffern folgen dieser direkt, d.h. '1' --> 49, '2' --> 50 usw.
Wenn du nun also z.B. '0' von '1' abziehst, so erhälst du folgenden Ausdruck: '1'-'0'=49-48=1. Das ist auch für die anderen Ziffern gültig, auch für die 0 selbst.
 

julia123

Erfahrenes Mitglied
#6
ok, dass hab ich jetzt verstanden vielen Dank!
Ich weiss ich nerve sicher manchmal aber ich muss :( .

Naja ok.

Ich glaube ein paar Sachen sind nicht klar was ich wirklich möchte:
Diesen Ausdruck : ((7+6)/(9-4))) in so eine Postfix-Darstellung[7, 6, +, 9, 4,-, /] umwandeln
Java:
else if (expr.charAt(pos) == '(') {
				char op;
				++pos;
				parseToPostfix(expr);
				// hier mein Problem
				op = expr.charAt(pos);// die Stelle wo ein +-/ oder *  positioniert ist
				++pos;
				parseToPostfix(expr);// es folgt eine Ziffer oder '(', muss! 

				result.add(new Const(op - '0'));// Hier würde ich jetzt mit diesen ASCII spielen z.b 42 -> *
				++pos; // ’)’
Ab Zeile 5 fangen meine Sorgen an.
Was ich jetzt möchte ist einfach diesen Vergleich wann es sich um ein *+- oder / handelt und dies irrgend wie in die Liste speichern.
Dann hab ich mir gedacht ich fang einfach mal damit an wenn er ein Operator sieht ein + immer einzufügen. Das mit dem unterscheiden kann ich dannach immer noch machen.

Hinzu kommt dass die Liste aus Expressions besteht also Objkete. Wie kann ich es machen das mir nicht so was ausgegeben wird:
[teil2.Expressions$Const@498b5a73, teil2.Expressions$Const@5bdf59bd, ] -> Das ist ja die Referenz auf das Objekt soweit ich weiss. Also benötige ich eine toString-Methode . Oder? In den einzelnen Expressions.

vielen lieben Dank schon mal!
 
#7
Diesen Ausdruck : ((7+6)/(9-4))) in so eine Postfix-Darstellung[7, 6, +, 9, 4,-, /] umwandeln
Ok, schon viel verständlicher.
Und diese ganzen verschiedenen Klassen, ist das irgendwie vorgeschrieben die zu machen?
Es wäre nämlich deutlich einfacher, darauf zu verzichten.
(als Ergebnis einfach ein Array/Liste von Strings oder so,
eventuell noch unterscheiden in Zahl/Operator)
 

julia123

Erfahrenes Mitglied
#8
ja, die Klassen oben sind vorgegeben.
Angeblich soll nur diese parseToPostfix-Methode leicht umgewandelt werden.(siehe vollständigen Quellcode oben).





Also so sieht mein momentaner Stand aus. Ich hab im Kommentar das eingefügt was ich für logisch erachtet hab.
Ok, mein result<Expressions> hat jetzt ein add Objekt drinne. Aber wie kann ich sagen das dieses Objekt ein + symbolisiert. (Wie kann ich später unterscheiden zwischen +-*/)
So ein paar detaliertere Typs wären echt cool.



Tut mir leid dass ich noch mal mein Beitrag bearbeite.Das oben könnt ihr ignorieren ( ich denke denn Betrag zu löschen ist nicht schön deswegen lass ich dass oben mal stehen ). Ok, zurück zu Thematik hier steh ich jetzt:
Java:
else if (expr.charAt(pos) == '(') {
				char op;
				++pos;
				Const tempZ1 = new Const(expr.charAt(pos) - '0');
				parseToPostfix(expr);
				op = expr.charAt(pos);
				++pos;
				parseToPostfix(expr);

				Const tempZ2 = new Const(expr.charAt(pos) - '0');

				if (op == '*') {
					result.add(new Mult(tempZ1, tempZ2));
				} else if (op == '+') {
					result.add(new Add(tempZ1, tempZ2));
				} else if (op == '/') {
					result.add(new Div(tempZ1, tempZ2));
				} else {
					result.add(new Sub(tempZ1, tempZ2));
				}
				// result.add(new Add(tempZ1, tempZ2));
				++pos; 
			}
Ich möchte jetzt eigentlich nur wissen ob das richtig ist, was ich da oben gemacht habe.
Anonsten wiess ich immer noch nicht wie ich dass ausführen kann. So dass nicht so etwas bei rauss kommt(Referenz auf das Objekt) :
teil2.Expressions$Const@77bdcbb2 teil2.Expressions$Const@77bdcbb2 teil2.Expressions$Const@77bdcbb2
 
Zuletzt bearbeitet:

HonniCilest

Erfahrenes Mitglied
#9
Ok, mein result<Expressions> hat jetzt ein add Objekt drinne. Aber wie kann ich sagen das dieses Objekt ein + symbolisiert. (Wie kann ich später unterscheiden zwischen +-*/)
Wenn ich es richtig verstehe sollte instanceof hier dein Freund sein.

Ist die parseToPostfix Methode wirklich die einzige die du verändern darfst? Mich irritiert nämlich noch einiges außerhalb dieser Methode...
 

julia123

Erfahrenes Mitglied
#10
public interface Expression {...}
public static abstract class ComplexExpression implements Expression {...}
public static class Const implements Expression {...}
public static class Add extends ComplexExpression {...}
public static class Sub extends ComplexExpression {...}
public static class Div extends ComplexExpression {...}
public static class Mult extends ComplexExpression {...}
Die hab ich implementiert.

Also du bist der Meinung das ich eine equals methode für die einzelnen Expressions erstelle. Oder wie soll ich das mit dem instanceof
realisieren. Das sagt ja nur das,ob das Objekt eine unterklasse von einer Klasse ist. Richtig?

Was mich aber besonders nervt ist dass ich einfach kein Ergebnis hab. Also wie schon gesagt das mit der Referenz ...
 

julia123

Erfahrenes Mitglied
#11
ok, ich hab das Problem am ende gelöst. Ichs schreib das nur noch mal rein für Andere.

Also was hab ich gemacht oder was musste gemacht werden,war einfahc nur eine toString() -Methode . In die einzelnen Klassen.
So sieht dann der spaß aus:


Das Problem ist meistens viel einfacher(zumindest am bei so anfänger Aufgaben) als wie man sich anstellt :(

viel spaß
 
Zuletzt bearbeitet:

Neue Beiträge