PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Java: Brauche Hilfe bei Programm: Bug in der Rekursion



daenerys
26.08.2008, 18:12
Hallo liebe Java-Programmierer!
Für Informatik in der Schule sollte ich jüngst einen Taschenrechner per Rekursion programmieren - der funktioniert bisher auch ganz gut, das Problem ist nur folgendes: Wird im eingegebenen Term (der mit Klammern enden und beginnen muss, damit das ganze funktioniert) eine neue Klammer geöffnet, funktioniert das Programm nicht mehr. Ohne innere Klammern funktioniert das ganze einwandfrei. Ich vermute, das das ganze etwas mit der Rekursion zu tun hat.
Es wäre sehr nett, wenn sich das jemand mal anschaut und vielleicht sogar den Fehler entdeckt. :)

package Rechner1;


/**
*
* @author Sara
*/
public class NewMain {

/**
* @param args the command line arguments
*/
public static void main(String[] args) {
Fenster fenster=new Fenster();
fenster.setBounds(20,20,600,300);
fenster.show();
}

}



package Rechner1;


/**
*
* @author Sara
*/
import java.awt.*;
import java.awt.event.*;

public class Fenster extends Frame{

public TextField eingabeTf=new TextField();
public TextField ausgabeTf=new TextField();
private Button button=new Button();
private MBAL bal=new MBAL();
public Fensterschließer wl=new Fensterschließer();
private Button oben=new Button();
public String eingabe;
public String ausgabe;
public Berechnung b=new Berechnung();
public Fenster fenster;
private char az;

public Fenster(){
// Aufbau des Fensters
setLayout(null);
setBackground(Color.lightGray);
eingabeTf.setBackground(Color.white);
eingabeTf.setForeground(Color.DARK_GRAY);
eingabeTf.setBounds(70,90,400,30);
eingabeTf.setText("Ihr Term muss mit Klammern beginnen und enden.");
ausgabeTf.setBackground(Color.gray);
ausgabeTf.setForeground(Color.black);
ausgabeTf.setBounds(70,140,400,30);
ausgabeTf.setText("Hier sehen sie das Ergebnis, wenn sie den Button drückten.");
button.setBackground(Color.green);
button.setForeground(Color.black);
button.setBounds(480,90,70,30);
button.addActionListener(bal);
button.setLabel("Berechnen");
oben.setBackground(Color.lightGray);
oben.setForeground(Color.black);
oben.setBounds(70,40,400,30);
oben.setLabel("Bitte geben sie ihren Term ein!");
this.add(eingabeTf);
this.add(ausgabeTf);
this.add(button);
this.add(oben);
this.addWindowListener(wl);
fenster=this;
b.vater=this;
}
public class Fensterschließer extends WindowAdapter{
public void windowClosing(WindowEvent e){
System.exit(0);
}
}
private class MBAL implements ActionListener{
public void actionPerformed(ActionEvent e){
ausgabeTf.setText("Wird berechnet...");
eingabe=eingabeTf.getText();
ausgabeTf.setText("Das Ergebnis ist: "+b.ausdruck(eingabe));
}
}
}



package Rechner1;


/**
*
* @author Sara
*/


public class Berechnung {

private int sg=1;
public int ergebnis;
public Fenster vater;
private double TE1,TE2,EF1,EF2,EK,EA;
private int ES, laenge,stellenweg=0;
private char k,o;
private String sust;
private boolean geht,p1=false,p2=false;
public String aktuell;

public Berechnung(){

}

//Methoden
public double ausdruck(String ein){
System.out.println("Ausdruck");
if (ein.charAt(0)=='(')
{
ein=ein.substring(1,ein.length()); // erstes Zeichen löschen
System.out.println("Ausdruck: Nach Klammer löschen: "+ein);
sg=signum(ein);
ein=aktuell;
System.out.println("Ausdruck: Nach Signum: "+aktuell);
TE1=term(ein);
ein=aktuell;
System.out.println("Ausdruck: Nach Term: "+aktuell);
TE1=TE1*sg;
System.out.println("TE1*sg: "+TE1);
for(int i=1;i<ein.length()-1;i++)
{
if (ein.charAt(0)=='+')
{
o='+';
ein=ein.substring(1,ein.length());
}
else
{
if (ein.charAt(0)=='-')
{
o='-';
ein=ein.substring(1,ein.length());
}
}
System.out.println("Ausdruck: o: "+o);
TE2=term(ein);
System.out.println("TE2: "+TE2);
ein=aktuell;
if(o=='-') TE1=TE1-TE2;
if(o=='+') TE1=TE1+TE2;
}
if (ein.charAt(0)==')')
{
return TE1;
}
}
else vater.ausgabeTf.setText(ein);
return TE1;
}
public int signum(String eingabe){
System.out.println("Signum");
if (eingabe.charAt(0)=='-')
{
ES=-1;
eingabe=eingabe.substring(1,eingabe.length());
}
else
{
if (eingabe.charAt(0)=='+')
{
eingabe=eingabe.substring(1,eingabe.length());
}
ES=1;
}
System.out.println("Signumende: "+eingabe);
aktuell=eingabe;
return ES;
}
public double term(String eingabe){
System.out.println("Term");
EF1=faktor(eingabe);
eingabe=aktuell;
k=eingabe.charAt(0);
p2=prob(k);
while (p2==true)
{
System.out.println("In der While-Schleife");
if (eingabe.charAt(0)=='*')
{
k='*';
eingabe=eingabe.substring(1,eingabe.length());
}
else
{
if (eingabe.charAt(0)=='/')
{
k='/';
eingabe=eingabe.substring(1,eingabe.length());
}
}
EF2=faktor(eingabe);
eingabe=aktuell;
if (k=='/') EF1=EF1/EF2;
else EF1=EF1*EF2;
k=eingabe.charAt(0);
p2=prob(k);
}
System.out.println("Term Ende: "+eingabe);
aktuell=eingabe;
return EF1;
}
public double faktor(String eingabe){
System.out.println("Faktor");
if (eingabe.charAt(0)=='(')
{
EA=ausdruck(eingabe);
eingabe=aktuell;
System.out.println("EA: "+EA);
return EA;
}
else
{
laenge=eingabe.length();
for(int i=1;i<laenge;i++)
{
sust=eingabe.substring(0,laenge-i);
try
{
EK=Double.parseDouble(sust);
}
catch (java.lang.NumberFormatException e)
{
geht=false;
continue;
}
geht=true;
eingabe=eingabe.substring(laenge-i,laenge);
aktuell=eingabe;
break;
}
}
System.out.println("EK: "+EK);
System.out.println("Faktor Ende: "+eingabe);
aktuell=eingabe;
return EK;
}
public boolean prob(char l)
{
p1=false;
if (l=='*')
{
p1=true;
}
else
{
if (l=='/')
{
p1=true;
}
else
{
if(l=='1')
{
p1=true;
}
else
{
if(l=='2')
{
p1=true;
}
else
{
if (l=='3')
{
p1=true;
}
else
{
if (l=='4')
{
p1=true;
}
else
{
if (l=='5')
{
p1=true;
}
else
{
if (l=='6')
{
p1=true;
}
else
{
if (l=='7')
{
p1=true;
}
else
{
if (l=='8')
{
p1=true;
}
else
{
if (l=='9')
{
p1=true;
}
else
{
if (l=='0')
{
p1=true;
}
else
{
p1=false;
}
}
}
}
}
}
}
}
}
}
}
}
// Ende der if-Reihe
System.out.println("prob liefert: "+p1);
return p1;
}
// Ende der Klasse
}




Zusätzliche Informationen:

Die Methode Ausdruck prüft, ob eine Klammer vorliegt und ruft dann Signum auf, anschließend Term und geht dann in folgende Schleife über: Solange eingabe noch Zeichen hat, überpüft sie erst, ob + oder - vorliegt und ruft dann Term auf. Ist diese Schleife beendet, wird geprüft, ob eine Klammer zu kommt.
Alle Methoden brauchen einen String und liefern eine Zahl (int oder double) zurück.
Faktor zieht entweder eine Konstante aus dem String oder ruft Ausdruck auf.
Die Methode prob ist nur behelfsmäßig und dazu da, Faktor oder die Überprüfung von * oder / solange aufzurufen, wie die Methoden auch mit dem ersten Zeichen des Strings etwas anfangen können. Es ist keine hohe Programmierkunst, ich weiß, aber es funktioniert.


So, ich hoffe, hier kann jemand etwas damit anfangen. Auf jeden Fall schon mal Dank an alle, die nach einem Fehler suchen!
Sollte es noch Fragen geben, bitte hier rein stellen.

Drakes
26.08.2008, 18:19
Benütze bitte die Code Tags: [*CODE][*/CODE] (ohne *)
Dann ist der Quellcode auch formatiert und ich hab wenigstens ne Chance, denn Code zu lesen. :p

daenerys
27.08.2008, 08:25
Oh, Sry ^^ Beitrag ist jetzt aktualisiert.