Subtrees hinzugefügt

This commit is contained in:
Dirk Zechnall 2025-01-05 21:22:02 +01:00
parent 155d0786a6
commit 3cc08a2004
443 changed files with 131415 additions and 0 deletions

7
Quellcodes/Alg_DS_Terme/.gitignore vendored Normal file
View file

@ -0,0 +1,7 @@
**/*.sh
**/*.class
**/*.ctxt
repo.adoc
repo_subtree.adoc
/alt
/hide

View file

@ -0,0 +1,77 @@
import static org.junit.Assert.*;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
/**
* Testet, ob die String-Umwandlung der Binärbäume korrekt funktioniert.
*
* @author Rainer Helfrich
* @version November 2020
*/
public class AlsStringTest
{
@Test
public void test1()
{
testAusfuehren("2*3 + 4*5", "2*3+4*5");
}
@Test
public void test2()
{
testAusfuehren("(12/6) /2", "12/6/2");
}
@Test
public void test3()
{
testAusfuehren(" 12/(6/2)", "12/(6/2)");
}
@Test
public void test4()
{
testAusfuehren("(2+3)*(4 +5)", "(2+3)*(4+5)");
}
@Test
public void test5()
{
testAusfuehren("3/2+9/(3+1) ", "3/2+9/(3+1)");
}
@Test
public void test6()
{
testAusfuehren("100/5/(9-8)", "100/5/(9-8)");
}
@Test
public void test7()
{
testAusfuehren("1*2-3*4+(5*6)-7*8", "1*2-3*4+5*6-7*8");
}
@Test
public void test8()
{
testAusfuehren("(1*2+3*4)*((5*6)-7*(89/10))", "(1*2+3*4)*(5*6-7*89/10)");
}
private void testAusfuehren(String term, String erwartet)
{
try
{
Binaerbaum<Symbol> b = TermParser.parse(term);
TermAuswerter t = new TermAuswerter();
String ergebnis = t.alsString(b);
assertEquals(erwartet, ergebnis.replaceAll("\\s", ""));
}
catch(Exception x)
{
assertTrue(x.getMessage(), false);
}
}
}

View file

@ -0,0 +1,77 @@
import static org.junit.Assert.*;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
/**
* Testet, ob die Auswertung der Binärbäume korrekt funktioniert.
*
* @author Rainer Helfrich
* @version November 2020
*/
public class AuswertungsTest
{
@Test
public void test1()
{
testAusfuehren("2*3+4*5", 26);
}
@Test
public void test2()
{
testAusfuehren("(12/6)/2", 1);
}
@Test
public void test3()
{
testAusfuehren("12/(6/2)", 4);
}
@Test
public void test4()
{
testAusfuehren("(2+3)*(4+5)", 45);
}
@Test
public void test5()
{
testAusfuehren("3/2+9/(3+1)", 3);
}
@Test
public void test6()
{
testAusfuehren("100/5/(9-8)", 20);
}
@Test
public void test7()
{
testAusfuehren("1*2-3*4+(5*6)-7*8", -36);
}
@Test
public void test8()
{
testAusfuehren("(1*2+3*4)*((5*6)-7*(89/10))", -364);
}
private void testAusfuehren(String term, int erwartet)
{
try
{
Binaerbaum<Symbol> b = TermParser.parse(term);
TermAuswerter t = new TermAuswerter();
int ergebnis = t.auswerten(b);
assertEquals(erwartet, ergebnis);
}
catch(Exception x)
{
assertTrue(x.getMessage(), false);
}
}
}

View file

@ -0,0 +1,63 @@
/**
* Ein Knoten eines Binärbaums
*
* @author Rainer Helfrich
* @version Oktober 2020
*/
public class Binaerbaum<T>
{
/**
* Der Datenwert des Knotens
*/
public T daten;
/**
* Der linke Kindbaum
*/
public Binaerbaum<T> links;
/**
* Der rechte Kindbaum
*/
public Binaerbaum<T> rechts;
/**
* Erzeugt einen Blattknoten mit leerem Datenwert
*/
public Binaerbaum()
{
this(null, null, null);
}
/**
* Erzeugt einen Knoten mit Datenwert und Kindern
* @param daten Der Datenwert
* @param links Der linke Kindbaum
* @param rechts Der rechte Kindbaum
*/
public Binaerbaum(T daten, Binaerbaum<T> links, Binaerbaum<T> rechts)
{
this.daten = daten;
this.links = links;
this.rechts = rechts;
}
/**
* Erzeugt einen Blattknoten mit Datenwert
* @param daten Der Datenwert
*/
public Binaerbaum(T daten)
{
this(daten, null, null);
}
/**
* Gibt zurück, ob der Knoten ein Blatt ist
* @return true, wenn der Knoten ein Blatt ist; false sonst
*/
public boolean istBlatt()
{
return links == null && rechts == null;
}
}

View file

@ -0,0 +1,5 @@
PROJEKTBEZEICHNUNG: Terme
PROJEKTZWECK: Implementieren Sie das Auswerten von Rechentermen sowie das Umwandeln in eine String-Darstellung
VERSION oder DATUM: November 2020
WIE IST DAS PROJEKT ZU STARTEN: Erzeugen Sie ein neues Objekt vom Typ TermFrame
AUTOR(EN): Rainer Helfrich, ZPG Informatik

View file

@ -0,0 +1,110 @@
/**
* Stellt ein Symbol eines Rechenterms dar.
* Frei nach der Abituraufgabe B3 von 2018
*
* @author Rainer Helfrich
* @version November 2020
*/
public class Symbol
{
/**
* Der Operator bzw. der Wert des Symbols
*/
private String wert;
/**
* Erzeugt ein neues Symbol.
* @param s Der Wert des Symbols
*/
public Symbol(String s)
{
wert = s;
}
/**
* Gibt zurück, ob es sich bei dem Symbol um einen Operator handelt.
* @return true, wenn es ein Operator ist; false sonst
*/
public boolean istOperator()
{
return "+-*/".contains(wert);
}
/**
* Gibt den Integer-Wert des Symbols zurück
* @return Den Integer-Wert des Symbols, wenn es sich um eine Zahl handelt; 0 sonst
*/
public int getInt()
{
if (!istOperator())
{
return Integer.parseInt(wert);
}
return 0;
}
/**
* Gibt zurück, ob es sich um einen Plus-Operator handelt
* @return true, wenn das Symbol "+" ist; false sonst
*/
public boolean istPlus()
{
return wert.equals("+");
}
/**
* Gibt zurück, ob es sich um einen Mal-Operator handelt
* @return true, wenn das Symbol "*" ist; false sonst
*/
public boolean istMal()
{
return wert.equals("*");
}
/**
* Gibt zurück, ob es sich um einen Minus-Operator handelt
* @return true, wenn das Symbol "-" ist; false sonst
*/
public boolean istMinus()
{
return wert.equals("-");
}
/**
* Gibt zurück, ob es sich um einen Geteilt-Operator handelt
* @return true, wenn das Symbol "/" ist; false sonst
*/
public boolean istGeteilt()
{
return wert.equals("/");
}
/**
* Gibt zurück, ob es sich um eine Punktrechnung handelt
* @return true, wenn das Symbol "*" oder "/" ist; false sonst
*/
public boolean istPunktRechnung()
{
return istMal() || istGeteilt();
}
/**
* Gibt zurück, ob es sich um eine Strichrechnung handelt
* @return true, wenn das Symbol "+" oder "-" ist; false sonst
*/
public boolean istStrichRechnung()
{
return istPlus() || istMinus();
}
/**
* Wandelt das Symbol in seine String-Darstellung um
* @return Die String-Darstellung des Symbols
*/
@Override
public String toString()
{
return wert;
}
}

View file

@ -0,0 +1,31 @@
/**
* Wertet einen Term aus, der als Rechenbaum gegeben ist
*
* @author Rainer Helfrich
* @version November 2020
*/
public class TermAuswerter
{
/**
* Wertet den Term, der durch den Binärbaum b gegeben ist, arithmetisch aus
* @param b Der auszuwertende Baum
* @return Das Zahlergebnis des Terms
*/
public int auswerten(Binaerbaum<Symbol> b)
{
//# TODO: Implementieren Sie die Auswertung des Rechenbaums n
return 0;
}
/**
* Wandelt den Term, der durch den Binärbaum b gegeben ist, in eine lineare Termdarstellung um
* @param b Der umzuwandelnde Term
* @return Der Term als lineare Zeichenkette
*/
public String alsString(Binaerbaum<Symbol> b)
{
//# TODO: Implementieren Sie die Umwandlung des Rechenbaums in eine lineare Textdarstellung
return "";
}
}

View file

@ -0,0 +1,142 @@
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
/**
*
* GUI zum Verarbeiten von Termen
* Hier sollte nichts verändert werden.
*
* @version 1.0 vom 05.11.2020
* @author Rainer Helfrich
*/
public class TermFrame extends JFrame
{
private JTextField jTextTerm = new JTextField();
private JTextArea jTextTree = new JTextArea("");
private JTextField jTextErgebnis = new JTextField();
public TermFrame() {
super();
setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
int frameWidth = 408;
int frameHeight = 580;
setSize(frameWidth, frameHeight);
Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
int x = (d.width - getSize().width) / 2;
int y = (d.height - getSize().height) / 2;
setLocation(x, y);
setTitle("Termauswertung");
setResizable(true);
Container cp = getContentPane();
cp.setLayout(null);
jTextTerm.setBounds(96, 8, 289, 25);
jTextTerm.setFont(new Font("Courier New", Font.PLAIN, 12));
cp.add(jTextTerm);
JScrollPane jTextArea1ScrollPane = new JScrollPane(jTextTree);
jTextArea1ScrollPane.setBounds(8, 40, 377, 465);
jTextTree.setEditable(false);
jTextTree.setFont(new Font("Courier New", Font.PLAIN, 12));
cp.add(jTextArea1ScrollPane);
jTextErgebnis.setBounds(96, 512, 289, 25);
jTextErgebnis.setEditable(false);
jTextErgebnis.setFont(new Font("Courier New", Font.PLAIN, 12));
cp.add(jTextErgebnis);
JLabel lErgebnis = new JLabel();
lErgebnis.setBounds(8, 512, 78, 20);
lErgebnis.setText("Ergebnis:");
cp.add(lErgebnis);
JLabel lTerm = new JLabel();
lTerm.setBounds(8, 8, 78, 20);
lTerm.setText("Term:");
cp.add(lTerm);
jTextTerm.getDocument().addDocumentListener(new DocumentListener() {
public void changedUpdate(DocumentEvent e) {
parseTerm();
}
public void removeUpdate(DocumentEvent e) {
parseTerm();
}
public void insertUpdate(DocumentEvent e) {
parseTerm();
}
});
addComponentListener(new ComponentAdapter() {
public void componentResized(ComponentEvent e) {
jTextArea1ScrollPane.setSize(getWidth()-31, getHeight()-115);
jTextErgebnis.setSize(getWidth()-119, 25);
jTextTerm.setSize(getWidth()-119, 25);
jTextErgebnis.setLocation(96, getHeight()-68);
lErgebnis.setLocation(8, getHeight()-68);
}
});
setMinimumSize(new Dimension(300, 300));
setVisible(true);
}
private void parseTerm()
{
jTextTree.setText("");
jTextErgebnis.setText("");
try
{
Binaerbaum<Symbol> rechenbaum = TermParser.parse(jTextTerm.getText());
String ausgabe = baumAnzeigen(rechenbaum);
if (rechenbaum != null)
{
TermAuswerter ta = new TermAuswerter();
int ergebnis = ta.auswerten(rechenbaum);
jTextErgebnis.setText(String.valueOf(ergebnis));
ausgabe += "\n=====================================\n\n";
ausgabe += ta.alsString(rechenbaum);
}
jTextTree.setText(ausgabe);
}
catch(Exception x)
{
jTextTree.setText(x.getMessage());
}
}
private String baumAnzeigen(Binaerbaum b)
{
if (b == null)
{
return "(leerer Baum)";
}
StringBuilder sb = new StringBuilder();
sb.append(b.daten+"\n");
if (b.links != null || b.rechts != null)
{
baumAnzeigen(b.links, "", true, sb);
baumAnzeigen(b.rechts, "", false, sb);
}
return sb.toString();
}
private void baumAnzeigen(Binaerbaum b, String indent, boolean left, StringBuilder sb)
{
sb.append(indent + (left ? "\u251C " : "\u2514 "));
if (b != null)
{
sb.append(b.daten+"\n");
if (b.links != null || b.rechts != null)
{
indent += (left ? "\u2502 " : " ");
baumAnzeigen(b.links, indent, true, sb);
baumAnzeigen(b.rechts, indent, false, sb);
}
}
else
{
sb.append("\n");
}
}
}

View file

@ -0,0 +1,164 @@
import java.util.ArrayList;
import java.util.Stack;
/**
* Wandelt einen als String gegebenen Term in einen Rechenbaum um
* Hier sollte nichts verändert werden.
*
* @author Rainer Helfrich
* @version November 2020
*/
public class TermParser
{
public static Binaerbaum<Symbol> parse(String term) throws Exception
{
ArrayList<String> out = tokenizeTerm(term);
ArrayList<Symbol> postfix = buildPostfix(out);
Binaerbaum<Symbol> rechenbaum = buildTree(postfix);
return rechenbaum;
}
private static Binaerbaum<Symbol> buildTree(ArrayList<Symbol> postfix) throws Exception
{
if (postfix.size() == 0)
{
return null;
}
Stack<Binaerbaum<Symbol>> stack = new Stack<Binaerbaum<Symbol>>();
for (Symbol s : postfix)
{
if (s.istOperator())
{
if (stack.size() < 2)
{
throw new Exception("Fehler: Zu viele Operatoren");
}
Binaerbaum<Symbol> r = stack.pop();
Binaerbaum<Symbol> l = stack.pop();
Binaerbaum<Symbol> n = new Binaerbaum<Symbol>(s, l, r);
stack.push(n);
}
else
{
stack.push(new Binaerbaum<Symbol>(s));
}
}
if (stack.size() != 1)
{
throw new Exception("Fehler: Zu wenige Operatoren");
}
return stack.pop();
}
private static ArrayList<Symbol> buildPostfix(ArrayList<String> infix) throws Exception
{
Stack<String> stack = new Stack<String>();
ArrayList<Symbol> postfix = new ArrayList<Symbol>();
for(String token : infix)
{
if (isNumeric(token))
{
postfix.add(new Symbol(token));
}
else if (token.equals("("))
{
stack.push(token);
}
else if (token.equals(")"))
{
while(true)
{
if (stack.isEmpty())
{
throw new Exception("Fehler: Ungültiger Term.");
}
String t = stack.pop();
if (t.equals("("))
{
break;
}
postfix.add(new Symbol(t));
}
}
else
{
while (!stack.isEmpty())
{
String top = stack.peek();
if ("+-*/".contains(top) && ("+-".contains(token) || "*/".contains(top)))
{
stack.pop();
postfix.add(new Symbol(top));
}
else
{
break;
}
}
stack.push(token);
}
}
while(!stack.isEmpty())
{
String top = stack.pop();
if (top.equals("("))
{
throw new Exception("Fehler: Ungültig geklammerter Term");
}
postfix.add(new Symbol(top));
}
return postfix;
}
private static boolean isNumeric(String s)
{
try
{
Integer.parseInt(s);
return true;
}
catch(Exception x)
{
}
return false;
}
private static ArrayList<String> tokenizeTerm(String strTerm) throws Exception
{
char[] term = strTerm.toCharArray();
ArrayList<String> tokens = new ArrayList<String>();
String numberToken = null;
for (char c : term)
{
if (Character.isDigit(c))
{
if (numberToken == null)
numberToken = "";
numberToken += String.valueOf(c);
}
else if ("+-*/()".contains(String.valueOf(c)) || Character.isWhitespace(c))
{
if (numberToken != null)
{
tokens.add(numberToken);
numberToken = null;
}
if (!Character.isWhitespace(c))
{
tokens.add(String.valueOf(c));
}
}
else
{
throw new Exception("Fehler: Ungültige Zeichen in Term.");
}
}
if (numberToken != null)
{
tokens.add(numberToken);
}
return tokens;
}
}

View file

@ -0,0 +1,122 @@
#BlueJ package file
dependency1.from=AuswertungsTest
dependency1.to=Binaerbaum
dependency1.type=UsesDependency
dependency10.from=TermAuswerter
dependency10.to=Symbol
dependency10.type=UsesDependency
dependency11.from=TermFrame
dependency11.to=Binaerbaum
dependency11.type=UsesDependency
dependency12.from=TermFrame
dependency12.to=Symbol
dependency12.type=UsesDependency
dependency13.from=TermFrame
dependency13.to=TermAuswerter
dependency13.type=UsesDependency
dependency14.from=TermFrame
dependency14.to=TermParser
dependency14.type=UsesDependency
dependency15.from=TermParser
dependency15.to=Binaerbaum
dependency15.type=UsesDependency
dependency16.from=TermParser
dependency16.to=Symbol
dependency16.type=UsesDependency
dependency2.from=AuswertungsTest
dependency2.to=Symbol
dependency2.type=UsesDependency
dependency3.from=AuswertungsTest
dependency3.to=TermAuswerter
dependency3.type=UsesDependency
dependency4.from=AuswertungsTest
dependency4.to=TermParser
dependency4.type=UsesDependency
dependency5.from=AlsStringTest
dependency5.to=Binaerbaum
dependency5.type=UsesDependency
dependency6.from=AlsStringTest
dependency6.to=Symbol
dependency6.type=UsesDependency
dependency7.from=AlsStringTest
dependency7.to=TermAuswerter
dependency7.type=UsesDependency
dependency8.from=AlsStringTest
dependency8.to=TermParser
dependency8.type=UsesDependency
dependency9.from=TermAuswerter
dependency9.to=Binaerbaum
dependency9.type=UsesDependency
editor.fx.0.height=739
editor.fx.0.width=925
editor.fx.0.x=788
editor.fx.0.y=67
objectbench.height=92
objectbench.width=760
package.divider.horizontal=0.6
package.divider.vertical=0.846749226006192
package.editor.height=540
package.editor.width=649
package.editor.x=80
package.editor.y=86
package.frame.height=746
package.frame.width=800
package.numDependencies=16
package.numTargets=7
package.showExtends=true
package.showUses=true
project.charset=UTF-8
readme.height=58
readme.name=@README
readme.width=47
readme.x=10
readme.y=10
target1.height=50
target1.name=TermFrame
target1.showInterface=false
target1.type=ClassTarget
target1.width=100
target1.x=70
target1.y=130
target2.height=50
target2.name=Binaerbaum
target2.showInterface=false
target2.type=ClassTarget
target2.width=130
target2.x=150
target2.y=10
target3.height=50
target3.name=Symbol
target3.showInterface=false
target3.type=ClassTarget
target3.width=80
target3.x=220
target3.y=200
target4.height=50
target4.name=AlsStringTest
target4.showInterface=false
target4.type=UnitTestTargetJunit4
target4.width=110
target4.x=280
target4.y=350
target5.height=50
target5.name=AuswertungsTest
target5.showInterface=false
target5.type=UnitTestTargetJunit4
target5.width=130
target5.x=140
target5.y=350
target6.height=50
target6.name=TermAuswerter
target6.showInterface=false
target6.type=ClassTarget
target6.width=120
target6.x=410
target6.y=240
target7.height=50
target7.name=TermParser
target7.showInterface=false
target7.type=ClassTarget
target7.width=100
target7.x=330
target7.y=70

View file

@ -0,0 +1,77 @@
import static org.junit.Assert.*;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
/**
* Testet, ob die String-Umwandlung der Binärbäume korrekt funktioniert.
*
* @author Rainer Helfrich
* @version November 2020
*/
public class AlsStringTest
{
@Test
public void test1()
{
testAusfuehren("2*3 + 4*5", "2*3+4*5");
}
@Test
public void test2()
{
testAusfuehren("(12/6) /2", "12/6/2");
}
@Test
public void test3()
{
testAusfuehren(" 12/(6/2)", "12/(6/2)");
}
@Test
public void test4()
{
testAusfuehren("(2+3)*(4 +5)", "(2+3)*(4+5)");
}
@Test
public void test5()
{
testAusfuehren("3/2+9/(3+1) ", "3/2+9/(3+1)");
}
@Test
public void test6()
{
testAusfuehren("100/5/(9-8)", "100/5/(9-8)");
}
@Test
public void test7()
{
testAusfuehren("1*2-3*4+(5*6)-7*8", "1*2-3*4+5*6-7*8");
}
@Test
public void test8()
{
testAusfuehren("(1*2+3*4)*((5*6)-7*(89/10))", "(1*2+3*4)*(5*6-7*89/10)");
}
private void testAusfuehren(String term, String erwartet)
{
try
{
Binaerbaum<Symbol> b = TermParser.parse(term);
TermAuswerter t = new TermAuswerter();
String ergebnis = t.alsString(b);
assertEquals(erwartet, ergebnis.replaceAll("\\s", ""));
}
catch(Exception x)
{
assertTrue(x.getMessage(), false);
}
}
}

View file

@ -0,0 +1,77 @@
import static org.junit.Assert.*;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
/**
* Testet, ob die Auswertung der Binärbäume korrekt funktioniert.
*
* @author Rainer Helfrich
* @version November 2020
*/
public class AuswertungsTest
{
@Test
public void test1()
{
testAusfuehren("2*3+4*5", 26);
}
@Test
public void test2()
{
testAusfuehren("(12/6)/2", 1);
}
@Test
public void test3()
{
testAusfuehren("12/(6/2)", 4);
}
@Test
public void test4()
{
testAusfuehren("(2+3)*(4+5)", 45);
}
@Test
public void test5()
{
testAusfuehren("3/2+9/(3+1)", 3);
}
@Test
public void test6()
{
testAusfuehren("100/5/(9-8)", 20);
}
@Test
public void test7()
{
testAusfuehren("1*2-3*4+(5*6)-7*8", -36);
}
@Test
public void test8()
{
testAusfuehren("(1*2+3*4)*((5*6)-7*(89/10))", -364);
}
private void testAusfuehren(String term, int erwartet)
{
try
{
Binaerbaum<Symbol> b = TermParser.parse(term);
TermAuswerter t = new TermAuswerter();
int ergebnis = t.auswerten(b);
assertEquals(erwartet, ergebnis);
}
catch(Exception x)
{
assertTrue(x.getMessage(), false);
}
}
}

View file

@ -0,0 +1,63 @@
/**
* Ein Knoten eines Binärbaums
*
* @author Rainer Helfrich
* @version Oktober 2020
*/
public class Binaerbaum<T>
{
/**
* Der Datenwert des Knotens
*/
public T daten;
/**
* Der linke Kindbaum
*/
public Binaerbaum<T> links;
/**
* Der rechte Kindbaum
*/
public Binaerbaum<T> rechts;
/**
* Erzeugt einen Blattknoten mit leerem Datenwert
*/
public Binaerbaum()
{
this(null, null, null);
}
/**
* Erzeugt einen Knoten mit Datenwert und Kindern
* @param daten Der Datenwert
* @param links Der linke Kindbaum
* @param rechts Der rechte Kindbaum
*/
public Binaerbaum(T daten, Binaerbaum<T> links, Binaerbaum<T> rechts)
{
this.daten = daten;
this.links = links;
this.rechts = rechts;
}
/**
* Erzeugt einen Blattknoten mit Datenwert
* @param daten Der Datenwert
*/
public Binaerbaum(T daten)
{
this(daten, null, null);
}
/**
* Gibt zurück, ob der Knoten ein Blatt ist
* @return true, wenn der Knoten ein Blatt ist; false sonst
*/
public boolean istBlatt()
{
return links == null && rechts == null;
}
}

View file

@ -0,0 +1,5 @@
PROJEKTBEZEICHNUNG: Terme
PROJEKTZWECK: Implementieren Sie das Auswerten von Rechentermen sowie das Umwandeln in eine String-Darstellung
VERSION oder DATUM: November 2020
WIE IST DAS PROJEKT ZU STARTEN: Erzeugen Sie ein neues Objekt vom Typ TermFrame
AUTOR(EN): Rainer Helfrich, ZPG Informatik

View file

@ -0,0 +1,110 @@
/**
* Stellt ein Symbol eines Rechenterms dar.
* Frei nach der Abituraufgabe B3 von 2018
*
* @author Rainer Helfrich
* @version November 2020
*/
public class Symbol
{
/**
* Der Operator bzw. der Wert des Symbols
*/
private String wert;
/**
* Erzeugt ein neues Symbol.
* @param s Der Wert des Symbols
*/
public Symbol(String s)
{
wert = s;
}
/**
* Gibt zurück, ob es sich bei dem Symbol um einen Operator handelt.
* @return true, wenn es ein Operator ist; false sonst
*/
public boolean istOperator()
{
return "+-*/".contains(wert);
}
/**
* Gibt den Integer-Wert des Symbols zurück
* @return Den Integer-Wert des Symbols, wenn es sich um eine Zahl handelt; 0 sonst
*/
public int getInt()
{
if (!istOperator())
{
return Integer.parseInt(wert);
}
return 0;
}
/**
* Gibt zurück, ob es sich um einen Plus-Operator handelt
* @return true, wenn das Symbol "+" ist; false sonst
*/
public boolean istPlus()
{
return wert.equals("+");
}
/**
* Gibt zurück, ob es sich um einen Mal-Operator handelt
* @return true, wenn das Symbol "*" ist; false sonst
*/
public boolean istMal()
{
return wert.equals("*");
}
/**
* Gibt zurück, ob es sich um einen Minus-Operator handelt
* @return true, wenn das Symbol "-" ist; false sonst
*/
public boolean istMinus()
{
return wert.equals("-");
}
/**
* Gibt zurück, ob es sich um einen Geteilt-Operator handelt
* @return true, wenn das Symbol "/" ist; false sonst
*/
public boolean istGeteilt()
{
return wert.equals("/");
}
/**
* Gibt zurück, ob es sich um eine Punktrechnung handelt
* @return true, wenn das Symbol "*" oder "/" ist; false sonst
*/
public boolean istPunktRechnung()
{
return istMal() || istGeteilt();
}
/**
* Gibt zurück, ob es sich um eine Strichrechnung handelt
* @return true, wenn das Symbol "+" oder "-" ist; false sonst
*/
public boolean istStrichRechnung()
{
return istPlus() || istMinus();
}
/**
* Wandelt das Symbol in seine String-Darstellung um
* @return Die String-Darstellung des Symbols
*/
@Override
public String toString()
{
return wert;
}
}

View file

@ -0,0 +1,103 @@
/**
* Wertet einen Term aus, der als Rechenbaum gegeben ist
*
* @author Rainer Helfrich
* @version November 2020
*/
public class TermAuswerter
{
/**
* Wertet den Term, der durch den Binärbaum b gegeben ist, arithmetisch aus
* @param b Der auszuwertende Baum
* @return Das Zahlergebnis des Terms
*/
public int auswerten(Binaerbaum<Symbol> b)
{
if (b.istBlatt())
{
return b.daten.getInt();
}
else
{
int l = auswerten(b.links);
int r = auswerten(b.rechts);
if (b.daten.istPlus())
{
return l + r;
}
else if (b.daten.istMal())
{
return l * r;
}
else if (b.daten.istMinus())
{
return l - r;
}
else
{
return l / r;
}
}
}
/**
* Wandelt den Term, der durch den Bin<EFBFBD>rbaum b gegeben ist, in eine lineare Termdarstellung um
* @param b Der umzuwandelnde Term
* @return Der Term als lineare Zeichenkette
*/
private boolean brauchtKlammer(Binaerbaum<Symbol> b, boolean links)
{
Binaerbaum<Symbol> kind = links ? b.links : b.rechts;
if (kind.istBlatt())
{
return false;
}
if (b.daten.istPunktRechnung())
{
if (kind.daten.istStrichRechnung())
return true;
if (!links && b.daten.istGeteilt())
return true;
return false;
}
if (!links && b.daten.istMinus() && b.rechts.daten.istStrichRechnung())
{
return true;
}
return false;
}
public String alsString(Binaerbaum<Symbol> b)
{
if (b.istBlatt())
{
return b.daten.toString();
}
String ergebnis = "";
if (brauchtKlammer(b, true))
{
ergebnis += "(";
}
ergebnis += alsString(b.links);
if (brauchtKlammer(b, true))
{
ergebnis += ")";
}
ergebnis += b.daten.toString();
if (brauchtKlammer(b, false))
{
ergebnis += "(";
}
ergebnis += alsString(b.rechts);
if (brauchtKlammer(b, false))
{
ergebnis += ")";
}
return ergebnis;
}
}

View file

@ -0,0 +1,142 @@
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
/**
*
* GUI zum Verarbeiten von Termen
* Hier sollte nichts verändert werden.
*
* @version 1.0 vom 05.11.2020
* @author Rainer Helfrich
*/
public class TermFrame extends JFrame
{
private JTextField jTextTerm = new JTextField();
private JTextArea jTextTree = new JTextArea("");
private JTextField jTextErgebnis = new JTextField();
public TermFrame() {
super();
setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
int frameWidth = 408;
int frameHeight = 580;
setSize(frameWidth, frameHeight);
Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
int x = (d.width - getSize().width) / 2;
int y = (d.height - getSize().height) / 2;
setLocation(x, y);
setTitle("Termauswertung");
setResizable(true);
Container cp = getContentPane();
cp.setLayout(null);
jTextTerm.setBounds(96, 8, 289, 25);
jTextTerm.setFont(new Font("Courier New", Font.PLAIN, 12));
cp.add(jTextTerm);
JScrollPane jTextArea1ScrollPane = new JScrollPane(jTextTree);
jTextArea1ScrollPane.setBounds(8, 40, 377, 465);
jTextTree.setEditable(false);
jTextTree.setFont(new Font("Courier New", Font.PLAIN, 12));
cp.add(jTextArea1ScrollPane);
jTextErgebnis.setBounds(96, 512, 289, 25);
jTextErgebnis.setEditable(false);
jTextErgebnis.setFont(new Font("Courier New", Font.PLAIN, 12));
cp.add(jTextErgebnis);
JLabel lErgebnis = new JLabel();
lErgebnis.setBounds(8, 512, 78, 20);
lErgebnis.setText("Ergebnis:");
cp.add(lErgebnis);
JLabel lTerm = new JLabel();
lTerm.setBounds(8, 8, 78, 20);
lTerm.setText("Term:");
cp.add(lTerm);
jTextTerm.getDocument().addDocumentListener(new DocumentListener() {
public void changedUpdate(DocumentEvent e) {
parseTerm();
}
public void removeUpdate(DocumentEvent e) {
parseTerm();
}
public void insertUpdate(DocumentEvent e) {
parseTerm();
}
});
addComponentListener(new ComponentAdapter() {
public void componentResized(ComponentEvent e) {
jTextArea1ScrollPane.setSize(getWidth()-31, getHeight()-115);
jTextErgebnis.setSize(getWidth()-119, 25);
jTextTerm.setSize(getWidth()-119, 25);
jTextErgebnis.setLocation(96, getHeight()-68);
lErgebnis.setLocation(8, getHeight()-68);
}
});
setMinimumSize(new Dimension(300, 300));
setVisible(true);
}
private void parseTerm()
{
jTextTree.setText("");
jTextErgebnis.setText("");
try
{
Binaerbaum<Symbol> rechenbaum = TermParser.parse(jTextTerm.getText());
String ausgabe = baumAnzeigen(rechenbaum);
if (rechenbaum != null)
{
TermAuswerter ta = new TermAuswerter();
int ergebnis = ta.auswerten(rechenbaum);
jTextErgebnis.setText(String.valueOf(ergebnis));
ausgabe += "\n=====================================\n\n";
ausgabe += ta.alsString(rechenbaum);
}
jTextTree.setText(ausgabe);
}
catch(Exception x)
{
jTextTree.setText(x.getMessage());
}
}
private String baumAnzeigen(Binaerbaum b)
{
if (b == null)
{
return "(leerer Baum)";
}
StringBuilder sb = new StringBuilder();
sb.append(b.daten+"\n");
if (b.links != null || b.rechts != null)
{
baumAnzeigen(b.links, "", true, sb);
baumAnzeigen(b.rechts, "", false, sb);
}
return sb.toString();
}
private void baumAnzeigen(Binaerbaum b, String indent, boolean left, StringBuilder sb)
{
sb.append(indent + (left ? "\u251C " : "\u2514 "));
if (b != null)
{
sb.append(b.daten+"\n");
if (b.links != null || b.rechts != null)
{
indent += (left ? "\u2502 " : " ");
baumAnzeigen(b.links, indent, true, sb);
baumAnzeigen(b.rechts, indent, false, sb);
}
}
else
{
sb.append("\n");
}
}
}

View file

@ -0,0 +1,164 @@
import java.util.ArrayList;
import java.util.Stack;
/**
* Wandelt einen als String gegebenen Term in einen Rechenbaum um
* Hier sollte nichts verändert werden.
*
* @author Rainer Helfrich
* @version November 2020
*/
public class TermParser
{
public static Binaerbaum<Symbol> parse(String term) throws Exception
{
ArrayList<String> out = tokenizeTerm(term);
ArrayList<Symbol> postfix = buildPostfix(out);
Binaerbaum<Symbol> rechenbaum = buildTree(postfix);
return rechenbaum;
}
private static Binaerbaum<Symbol> buildTree(ArrayList<Symbol> postfix) throws Exception
{
if (postfix.size() == 0)
{
return null;
}
Stack<Binaerbaum<Symbol>> stack = new Stack<Binaerbaum<Symbol>>();
for (Symbol s : postfix)
{
if (s.istOperator())
{
if (stack.size() < 2)
{
throw new Exception("Fehler: Zu viele Operatoren");
}
Binaerbaum<Symbol> r = stack.pop();
Binaerbaum<Symbol> l = stack.pop();
Binaerbaum<Symbol> n = new Binaerbaum<Symbol>(s, l, r);
stack.push(n);
}
else
{
stack.push(new Binaerbaum<Symbol>(s));
}
}
if (stack.size() != 1)
{
throw new Exception("Fehler: Zu wenige Operatoren");
}
return stack.pop();
}
private static ArrayList<Symbol> buildPostfix(ArrayList<String> infix) throws Exception
{
Stack<String> stack = new Stack<String>();
ArrayList<Symbol> postfix = new ArrayList<Symbol>();
for(String token : infix)
{
if (isNumeric(token))
{
postfix.add(new Symbol(token));
}
else if (token.equals("("))
{
stack.push(token);
}
else if (token.equals(")"))
{
while(true)
{
if (stack.isEmpty())
{
throw new Exception("Fehler: Ungültiger Term.");
}
String t = stack.pop();
if (t.equals("("))
{
break;
}
postfix.add(new Symbol(t));
}
}
else
{
while (!stack.isEmpty())
{
String top = stack.peek();
if ("+-*/".contains(top) && ("+-".contains(token) || "*/".contains(top)))
{
stack.pop();
postfix.add(new Symbol(top));
}
else
{
break;
}
}
stack.push(token);
}
}
while(!stack.isEmpty())
{
String top = stack.pop();
if (top.equals("("))
{
throw new Exception("Fehler: Ungültig geklammerter Term");
}
postfix.add(new Symbol(top));
}
return postfix;
}
private static boolean isNumeric(String s)
{
try
{
Integer.parseInt(s);
return true;
}
catch(Exception x)
{
}
return false;
}
private static ArrayList<String> tokenizeTerm(String strTerm) throws Exception
{
char[] term = strTerm.toCharArray();
ArrayList<String> tokens = new ArrayList<String>();
String numberToken = null;
for (char c : term)
{
if (Character.isDigit(c))
{
if (numberToken == null)
numberToken = "";
numberToken += String.valueOf(c);
}
else if ("+-*/()".contains(String.valueOf(c)) || Character.isWhitespace(c))
{
if (numberToken != null)
{
tokens.add(numberToken);
numberToken = null;
}
if (!Character.isWhitespace(c))
{
tokens.add(String.valueOf(c));
}
}
else
{
throw new Exception("Fehler: Ungültige Zeichen in Term.");
}
}
if (numberToken != null)
{
tokens.add(numberToken);
}
return tokens;
}
}

View file

@ -0,0 +1,122 @@
#BlueJ package file
dependency1.from=TermFrame
dependency1.to=Binaerbaum
dependency1.type=UsesDependency
dependency10.from=AuswertungsTest
dependency10.to=Symbol
dependency10.type=UsesDependency
dependency11.from=AuswertungsTest
dependency11.to=TermAuswerter
dependency11.type=UsesDependency
dependency12.from=AuswertungsTest
dependency12.to=TermParser
dependency12.type=UsesDependency
dependency13.from=TermParser
dependency13.to=Binaerbaum
dependency13.type=UsesDependency
dependency14.from=TermParser
dependency14.to=Symbol
dependency14.type=UsesDependency
dependency15.from=TermAuswerter
dependency15.to=Binaerbaum
dependency15.type=UsesDependency
dependency16.from=TermAuswerter
dependency16.to=Symbol
dependency16.type=UsesDependency
dependency2.from=TermFrame
dependency2.to=Symbol
dependency2.type=UsesDependency
dependency3.from=TermFrame
dependency3.to=TermAuswerter
dependency3.type=UsesDependency
dependency4.from=TermFrame
dependency4.to=TermParser
dependency4.type=UsesDependency
dependency5.from=AlsStringTest
dependency5.to=Binaerbaum
dependency5.type=UsesDependency
dependency6.from=AlsStringTest
dependency6.to=Symbol
dependency6.type=UsesDependency
dependency7.from=AlsStringTest
dependency7.to=TermAuswerter
dependency7.type=UsesDependency
dependency8.from=AlsStringTest
dependency8.to=TermParser
dependency8.type=UsesDependency
dependency9.from=AuswertungsTest
dependency9.to=Binaerbaum
dependency9.type=UsesDependency
editor.fx.0.height=739
editor.fx.0.width=1201
editor.fx.0.x=380
editor.fx.0.y=62
objectbench.height=94
objectbench.width=760
package.divider.horizontal=0.6
package.divider.vertical=0.8488023952095808
package.editor.height=560
package.editor.width=649
package.editor.x=948
package.editor.y=241
package.frame.height=768
package.frame.width=800
package.numDependencies=16
package.numTargets=7
package.showExtends=true
package.showUses=true
project.charset=UTF-8
readme.height=58
readme.name=@README
readme.width=47
readme.x=10
readme.y=10
target1.height=50
target1.name=TermFrame
target1.showInterface=false
target1.type=ClassTarget
target1.width=100
target1.x=70
target1.y=130
target2.height=50
target2.name=Binaerbaum
target2.showInterface=false
target2.type=ClassTarget
target2.width=130
target2.x=150
target2.y=10
target3.height=50
target3.name=Symbol
target3.showInterface=false
target3.type=ClassTarget
target3.width=80
target3.x=220
target3.y=200
target4.height=50
target4.name=AlsStringTest
target4.showInterface=false
target4.type=UnitTestTargetJunit4
target4.width=110
target4.x=210
target4.y=420
target5.height=50
target5.name=AuswertungsTest
target5.showInterface=false
target5.type=UnitTestTargetJunit4
target5.width=130
target5.x=430
target5.y=160
target6.height=50
target6.name=TermAuswerter
target6.showInterface=false
target6.type=ClassTarget
target6.width=120
target6.x=400
target6.y=300
target7.height=50
target7.name=TermParser
target7.showInterface=false
target7.type=ClassTarget
target7.width=100
target7.x=330
target7.y=70

View file

@ -0,0 +1,11 @@
= Material :
|===
|Zuordnung|
|Klassenstufe|
|Bildungsplanbezug |
|Werkzeug|
|Autoren|
|===
== Inhalt