AundD

hiall

Mitglied
hi,

ich bearbeite grade eine Aufgabe und komm nicht weiter.

Java:
public class ExpressionsTest {
	@Test
	public void testShouldResultInEqualSyntaxTrees() {
		Expression expr1 = new Mult(new Const(5), new Div(new Sub(new Mult(
				new Add(new Const(2), new Const(3)), new Const(5)),
				new Const(5)), new Const(5)));
		Expression expr2 = Expressions.parse("(3*((((2+3)*2)-5)/5))");
		assertTrue(expr1.equals(expr2));
	}

	@Test
	public void testShouldResultInCorrectEvaluation() {
		Expression expr = Expressions.parse("(3*((((2+3)*2)-5)/5))");
		assertEquals(3, expr.evaluate());
	}
}
Diesen Test muss ich zum laufen bringen. Das heißt Test 1 -> Diesen Ausdruck 3*((((2+3)*2)-5)/5)) ->
so umwandeln 2,3,+,2,*,5,-,5,/,3,* (ich hoffe ic hhab mich nicht verguckt)
Test2 -> das ganze einfahc ausrechenn (3*((((2+3)*2)-5)/5)) = 3.

Ein großer Teil wurd mir schon vorgegeben. Ich hab im Kommentar die Teile Kommentiert was ich noch mal extra implementiert hab:
Java:
public class Expressions {
	private Expressions() {
	}

	
	public interface Expression {
		int evaluate();

	}

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

		public String toString() {
			return null;
		}

		public ComplexExpression(Expression x, Expression y) {

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

		}

		@Override
		public boolean equals(Object o) {

			if (o == null)
				return false;

			if (o == this)
				return true;

			if (!o.getClass().equals(getClass()))
				return false;

			ComplexExpression that = (ComplexExpression) o;

			return this.x.equals(that.x) && this.y.equals(that.y);

			// HashCode

		}

		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 String toString() { // verändert
			return y + "";
		}

		@Override
		public int evaluate() {

			return y;
		}

	}

	public static class Add extends ComplexExpression {

		public Add(Expression x, Expression y) {

			super(x, y);

		}

		@Override
		public String toString() {//verändert

			return "+";
		}

		@Override
		public int evaluate() {

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

	}
// ... Mult,Sub,Div sehen wie Add aus hab ich mal weggelassen um Platz zu sparren
private static class ToPostfix {
		private int pos = 0;
		private Stack<Expression> result = new Stack<>();//verändert war eine Liste

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

		public Stack<Expression> get() {//verändert war eine Liste
			return result;
		}

		// hab ich komplett verändert
		private Expression parse(String expr) {//verändert
			if (istZiffer(expr.charAt(pos))) {
				result.push(new Const(expr.charAt(pos) - '0'));// '1'-'0'=49-48=1.
				++pos;
				// zB. (2+2)
			} else if (expr.charAt(pos) == '(') {
				char op;
				++pos;
				Const tempZ1 = new Const(expr.charAt(pos) - '0');
				parse(expr);
				op = expr.charAt(pos);
				++pos;
				parse(expr);// rekusion ziffer zuerst 2,6

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

				if (op == '*') {
					result.push(new Mult(tempZ1, tempZ2));
				} else if (op == '+') {
					result.push(new Add(tempZ1, tempZ2));
				} else if (op == '/') {
					result.push(new Div(tempZ1, tempZ2));
				} else {
					result.push(new Sub(tempZ1, tempZ2));
				}
				++pos; 
			}
			return null;
		}

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

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

Jetzt hab ich ein paar Fragen. Auf meinem Blatt steht dass ich eine Methode
boolean equals(Object o) erstellen soll. Ok ich hab das jetzt getan. Ist die richtig? Und wieso brauch ich die, wann vergleich ich denn diese Objekte. Da feht mir der ansatz. Ich hab ja eine string den nich übergegen bekomme jetzt vergleich ich einfach die Zeichen dachte ich mir also Primitivedatentypen
if('+'==expr.charAt(pos)) dann ...

Vielleicht kann mir jemand auch noch paar gute Typs geben bin am verzweiflen. Wo ich ansetzten kann. Das ich das alles Rekursiv machen muss ist mir klar weill das ein Baum ist ... Und wegen Stack Last in Last out.

So eine kleine Anleitung von einem Profi wäre echt cool :)


liebe grüße
 

rme

Top Contributor
Hallo,

deine equals-Methode sieht gut aus. Wenn ich das richtig sehe, wird die aber auch rekursiv aufgerufen, weil x und y selbst wieder Expressions sind. Das bedeutet, dass alle Implementierungen (momentan offenbar nur Const) von Expression auch eine equals-Methode brauchen, damit die Rekursion irgendwann vernünftig aufhört. Wenn du das nicht machst, wird die Standard-Implementierung von equals verwendet, die nur wahr ist, wenn die Objekte tatsächlich auf den gleichen Wert im Speicher zeigen. In "3+3" würdest du zweimal eine Const mit dem Wert 3 erzeugen, das Standard-Equals würde die aber nicht als gleich werten.

Die equals-Methode wird sehr oft implizit aufgerufen, wenn man mit Datenstrukturen arbeitet. Wenn man sie beispielsweise in einen Hash einfügt (z.B. HashSet), dann kann es ja passieren, dass es zu einer Kollision kommt. Das HashSet könnte dann zur Sondierung eine verkettete Liste anlegen und mehrere Elemente, die den gleichen Hash-Wert haben, in der Liste speichern. Wenn nun nach einem Element gesucht wird, muss ja irgendwie geprüft werden, welches Element in der Liste das korrekte ist - dafür ruft HashSet dann equals auf.
 

hiall

Mitglied
erst mal danke,


Hab leider ein kleines Problem bei meiner equals-Methode hab die Fehler-Meldung im Kommentar hinterlegt.
Java:
public static class Const implements Expression {

		private int y;

		public Const(int y) {

			this.y = y;

		}

		@Override
		public String toString() { // verändert
			return y + "";
		}

		@Override
		public int evaluate() {

			return y;
		}

		@Override
		public boolean equals(Object o) {

			if (o == null)
				return false;

			if (o == this)
				return true;

			if (!o.getClass().equals(getClass()))
				return false;

			Expression that = (Expression) o;

			/*
			 * Multiple markers at this line - y cannot be resolved or is not a
			 * field - y cannot be resolved or is not a field
			 */
			return this.y.equals(that.y);
			

		}

	}


Ok, anschliessend dazu weiss ich immer noch nicht wirklich wie ich an die Lösung des Problems komme. Also die Aufgabe löse.

Eine Equals-Methode schön und gut aber wo kommt die zum einsatz. Ich hab das nicht ganz verstanden.
 

rme

Top Contributor
y ist bei dir ein primitiver Datentyp, da gibt es keine Methoden wie equals. Du musst den Vergleich in dem Fall einfach mit dem ==-Operator durchführen.

Wenn ich das richtig sehe, kommt equals bisher auch nicht indirekt zum Eisatz - vielleicht wird das im Rahmen der Aufgabe noch nötig werden?
 

hiall

Mitglied
Hatte beides versucht funktioniert nicht.

Java:
public static class Const implements Expression {

		private int y;

		public Const(int y) {

			this.y = y;

		}

		@Override
		public String toString() { // verändert
			return y + "";
		}

		@Override
		public int evaluate() {

			return y;
		}

		@Override
		public boolean equals(Object o) {

			if (o == null)
				return false;

			if (o == this)
				return true;

			if (!o.getClass().equals(getClass()))
				return false;

			Expression that = (Expression) o;

			/*
			 * Multiple markers at this line - y cannot be resolved or is not a
			 * field - y cannot be resolved or is not a field
			 */
			return y == that.y;
			

		}

	}

Hier hab ich mal eine Voraufgabe gemacht. Vielleicht ist die der Schlüssel damit ich versthe wass ich machen soll. Hier bekomme ich eine Liste übegeben. Mit Expressions. Naja hier komm ich auch nicht weiter vielleicht kann mir wer wieter helfen.
Java:
public static Expression toTree(List<Expression> expressionList) {
		Stack<Expression> stack = new Stack<>();
		// Man stapelt, von links nach rechts gehend, die Elemente
		for (Expression e : expressionList) {
			if (e instanceof Const) {// eine zahl
				stack.push(e);
			} else if (e instanceof ComplexExpression) {// abgefragt ob es ein
														// Knoten ist +-/*
				// zwie obersten Stapelelemente verknüpft
				Expression temp1 = stack.pop();
				Expression temp2 = stack.pop();
				temp1.evaluate();

                                // wie soll ich vergleichen
				if (e.equals(new Add(new Const(temp1.evaluate()), new Const(
						temp2.evaluate())))) {

					stack.push(new Add(new Const(temp1.evaluate()), new Const(
							temp2.evaluate())));
				}
					//.... das gleiche mit Mult, Div, Sub
	
			} else {
				throw new IllegalArgumentException();
			}
		}
		return stack.pop();// müsste die wurzel sein
	}
 

rme

Top Contributor
In Zeile 34 castest du "o" auf Expression, aber du bist hier in einer Spezialisierung davon und musst auf Const casten, damit du auf y zugreifen kannst.
 

Oben