Taschenrechner mit mehreren Rechnungen

niklas551

Mitglied
Hallo zusammen,
ich hab mich hier mal angemeldet, da ich ein wenig Hilfe benötige und ich durch googeln nicht weiter kam.
Zu meiner Situation:
Ich verwende Eclipse Photon Release (4.8.0) und baue meine GUI mit WidowBuilder Pro Version 1.9.1 (Download Link:https://www.eclipse.org/windowbuilder/download.php)
So... ich bin dabei einen Taschenrechner zu programmieren, der in der letzten Version, 1 zu 1 wie der Windows 10 Taschenrechner aussehen und funktionieren soll. Natürlich ist das Aussehen jetzt erstmal komplett egal.
Bisher habe ich eine ausreichende GUI erstellt. Zu den Knöpfen, habe ich ein Label(labFront), indem alle aktiven Zahlen hineingeschrieben werden und ein weiteres Label(labBack), indem alle Rechnungen hineingeschrieben erden sollen, bis man "=" drückt. Funktioniert fast wie bei dem Win10 Taschenrechner. Ich habe es auch schon geschafft, 2 Zaheln richtig zu berechnen...
Jedoch jetzt will ich mehrere Zahlen und Operatoren eingeben zb.: 4+15-3*2. Und da kommt mein Problem.. ich weiss nicht wie.... Meine Idee war es im Hintergrund immer das Ergebnis zu speichern (4+15 = 19 --> im Hintergund speichern... -3 = 16 im Hintergrund usw.) Habe es schon mit Arrays, Variablen überschreiben,.. versucht aber nie zum gewünschten Ergebnis gekommen. Hoffe es war einigermaßen verständlich erklärt und jemand kann mir weiterhelfen. Mir reicht es auch zu wissen, wie es mit Zahl 1 und dem Operator Plus funktioniert, den Rest übertrage ich auf die andren Funktionen:) Im Endeffekt: Er soll das gleiche machen wie der Win10 Taschenrechner...
Zum Code: https://pastebin.com/zg8PTwjN

Falls ihr noch mehr Infos benötigt einfach Fragen. Vielen Dank schonmal im Vorraus!:)

P.S. hoffe die Frage wurde noch nicht gestellt, weil hatte sie niergens gefunden
 

mihe7

Top Contributor
Meine Idee war es im Hintergrund immer das Ergebnis zu speichern (4+15 = 19 --> im Hintergund speichern... -3 = 16 im Hintergrund usw.)
Und schon hast Du ein Problem, denn wenn auf -3 noch *16 folgt, musst Du erst -3*16 ausrechnen.

Wenn Du das wirklich selbst implementieren willst, musst Du den Ausdruck parsen und in einen abstrakten Syntaxbaum überführen.

https://de.wikipedia.org/wiki/Abstrakter_Syntaxbaum
https://courses.cs.washington.edu/courses/cse373/17au/project1/project1-2.html

P.S. hoffe die Frage wurde noch nicht gestellt, weil hatte sie niergens gefunden
Hm.. auf die Idee, einen Taschenrechner zu programmieren, sind bestimmt schon zwei, drei andere gekommen ;)
 

niklas551

Mitglied
Okay, hier nochmal mein Code:
Java:
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JButton;
import javax.swing.JTextField;
import java.awt.event.ActionListener;
import java.awt.geom.Ellipse2D;
import java.lang.invoke.LambdaConversionException;
import java.util.regex.Pattern;
import java.awt.event.ActionEvent;
import java.awt.Color;
import java.awt.Font;
import java.awt.Window;
import java.awt.Window.Type;
import java.awt.SystemColor;
import javax.swing.UIManager;
import javax.swing.JSeparator;
import javax.swing.JToolBar;
import javax.swing.JComboBox;
import java.awt.Panel;
import javax.swing.JLabel;
import javax.swing.JEditorPane;
import javax.swing.DropMode;
import javax.swing.JTextArea;
import javax.swing.JTextPane;
import javax.swing.JFormattedTextField;
import javax.swing.SwingConstants;


public class Calculator {

   private JFrame frmRechner;
   private JButton btnMinus;
   private JButton btnMal;
   private JButton btnTeilen;
   private JButton btnErgebnis;
   private JButton btnEins;
   private JButton btnZwei;
   private JButton btnDrei;
   private JButton btnVier;
   private JButton btnFuenf;
   private JButton btnSechs;
   private JButton btnSieben;
   private JButton btnAcht;
   private JButton btnNeun;
   private JButton btnNull;
   private JButton btnBack;
   private JLabel labBack;

   //Variablen
   double num;
   String a;
   int calc;
   String strOp;
   private JLabel labFront;
   
   public Calculator() {
       initialize();
   }

   //Sollte letzten 2 Eingaben ausgeben, nicht wirklich im Gebrauch
   public void Rechnen() {
       double ergGleich;
       switch(calc) {
       case 1:
           ergGleich = num + Double.parseDouble(labFront.getText());
           labFront.setText(Double.toString(ergGleich));
           labBack.setText("");
           break;
       case 2:
           ergGleich = num - Double.parseDouble(labFront.getText());
           labFront.setText(Double.toString(ergGleich));
           labBack.setText("");
           break;
       case 3:
           ergGleich = num * Double.parseDouble(labFront.getText());
           labFront.setText(Double.toString(ergGleich));
           labBack.setText("");
           break;
       case 4:
           ergGleich = num / Double.parseDouble(labFront.getText());
           labFront.setText(Double.toString(ergGleich));
           labBack.setText("");
           break;
       }
       
   }
   
   //Wenn Zahl gedrückt
   public void NumberPressed(String i){
   
   labFront.setText(labFront.getText() + i);
   
   }
   
   
   //Wenn Operator gedrückt
   public void OperatorPressed(String op) {
       double numb1 = 0, numb2, erg;
       
       numb2 = Double.parseDouble(labFront.getText()); //speichert Eingabe in Variable num2
   
       
       if(labBack.getText().endsWith("+")) { //Prüft ob ein Operator schon eingegeben ist
           numb1 += numb2; //Wert soll, wenn Operator schon eingegeben ist, an numb1 gegeben werden
           numb2 = Double.parseDouble(labFront.getText()); //Hier sollte dann 2.Zahl eingelesen werden
           erg = numb1 + numb2; //hier sollen dann Zahlen (in dem Fall addiert werden)
           labFront.setText(Double.toString(erg)); //Ergebnis wird ausgegeben
           labBack.setText(labBack.getText() + numb2 + op); //Zahl mit Operator in Hintergrund geschrieben
       }
       else { //Soll passieren wenn noch noch kein Operator vorher eingeben wurde
           labBack.setText(labBack.getText() + numb2 + op);
           labFront.setText("");
       }
       
       }
       
       private void initialize() {
       frmRechner = new JFrame();
       frmRechner.getContentPane().setForeground(new Color(0, 0, 0));
       frmRechner.setBackground(SystemColor.controlHighlight);
       frmRechner.setForeground(Color.LIGHT_GRAY);
       frmRechner.setTitle("Rechner");
       frmRechner.getContentPane().setBackground(UIManager.getColor("menu"));
       frmRechner.setBounds(100, 100, 320, 510);
       frmRechner.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
       frmRechner.getContentPane().setLayout(null);
       
       //Knopf addieren (+)
       JButton btnAddieren = new JButton("+");
       btnAddieren.setFont(new Font("Tahoma", Font.PLAIN, 15));
       btnAddieren.setBackground(SystemColor.controlHighlight);
       btnAddieren.setForeground(Color.BLACK);
       btnAddieren.addActionListener(new ActionListener() {
           public void actionPerformed(ActionEvent arg0) {
               calc = 1;
               OperatorPressed(btnAddieren.getText());
               
           }
       });
       btnAddieren.setBounds(220, 350, 70, 40);
       frmRechner.getContentPane().add(btnAddieren);
       
       //Knopf Subtrahieren (-)
       btnMinus = new JButton("-");
       btnMinus.setFont(new Font("Tahoma", Font.PLAIN, 15));
       btnMinus.setBackground(SystemColor.controlHighlight);
       btnMinus.addActionListener(new ActionListener() {
           public void actionPerformed(ActionEvent e) {
               calc = 2;
               OperatorPressed(btnMinus.getText());
           }
       });
       btnMinus.setBounds(220, 310, 70, 40);
       frmRechner.getContentPane().add(btnMinus);
       
       //Knopf Multiplizieren (*)
       btnMal = new JButton("*");
       btnMal.setFont(new Font("Tahoma", Font.PLAIN, 15));
       btnMal.setBackground(SystemColor.controlHighlight);
       btnMal.addActionListener(new ActionListener() {
           public void actionPerformed(ActionEvent e) {
               strOp = btnMal.getText();
               OperatorPressed(btnMal.getText());
           }
       });
       btnMal.setBounds(220, 270, 70, 40);
       frmRechner.getContentPane().add(btnMal);
       
       //Knopf Dividieren (/)
       btnTeilen = new JButton("/");
       btnTeilen.setFont(new Font("Tahoma", Font.PLAIN, 15));
       btnTeilen.setBackground(SystemColor.controlHighlight);
       btnTeilen.addActionListener(new ActionListener() {
           public void actionPerformed(ActionEvent e) {
               strOp = btnTeilen.getText();
               OperatorPressed(btnTeilen.getText());
           }
       });
       btnTeilen.setBounds(220, 230, 70, 40);
       frmRechner.getContentPane().add(btnTeilen);
       
       //Knopf Ergebnis (=)
       btnErgebnis = new JButton("=");
       btnErgebnis.addActionListener(new ActionListener() {
           public void actionPerformed(ActionEvent e) {
               Rechnen();
               
           }
       });
       btnErgebnis.setBackground(SystemColor.controlHighlight);
       btnErgebnis.setBounds(220, 390, 70, 40);
       frmRechner.getContentPane().add(btnErgebnis);
       
       //Knopf Eins (1)
       btnEins = new JButton("1");
       btnEins.setForeground(new Color(0, 0, 0));
       btnEins.addActionListener(new ActionListener() {
           public void actionPerformed(ActionEvent arg0) {
               NumberPressed(btnEins.getText());
               
           }
       });
       btnEins.setFont(new Font("Tahoma", Font.BOLD, 20));
       btnEins.setBackground(SystemColor.text);
       btnEins.setBounds(10, 350, 70, 40);
       frmRechner.getContentPane().add(btnEins);
       
       btnZwei = new JButton("2");
       btnZwei.setBounds(80, 350, 70, 40);
       frmRechner.getContentPane().add(btnZwei);
       btnZwei.setForeground(new Color(0, 0, 0));
       btnZwei.addActionListener(new ActionListener() {
           public void actionPerformed(ActionEvent arg0) {
               NumberPressed(btnZwei.getText());
               
           }
       });
       btnZwei.setFont(new Font("Tahoma", Font.BOLD, 20));
       btnZwei.setBackground(SystemColor.text);
       
       //Knopf Drei (3)
       btnDrei = new JButton("3");
       btnDrei.setForeground(new Color(0, 0, 0));
       btnDrei.addActionListener(new ActionListener() {
           public void actionPerformed(ActionEvent e) {
               NumberPressed(btnDrei.getText());
           
           }
       });
       btnDrei.setFont(new Font("Tahoma", Font.BOLD, 20));
       btnDrei.setBackground(SystemColor.text);
       btnDrei.setBounds(150, 350, 70, 40);
       frmRechner.getContentPane().add(btnDrei);
       
       //Knopf Vier (4)
       btnVier = new JButton("4");
       btnVier.setForeground(new Color(0, 0, 0));
       btnVier.addActionListener(new ActionListener() {
           public void actionPerformed(ActionEvent e) {
               NumberPressed(btnVier.getText());
               
           }
       });
       btnVier.setFont(new Font("Tahoma", Font.BOLD, 20));
       btnVier.setBackground(SystemColor.text);
       btnVier.setBounds(10, 310, 70, 40);
       frmRechner.getContentPane().add(btnVier);
       
       //Knopf Fünf (5)
       btnFuenf = new JButton("5");
       btnFuenf.setForeground(new Color(0, 0, 0));
       btnFuenf.addActionListener(new ActionListener() {
           public void actionPerformed(ActionEvent e) {
               NumberPressed(btnFuenf.getText());
               
           }
       });
       btnFuenf.setFont(new Font("Tahoma", Font.BOLD, 20));
       btnFuenf.setBackground(SystemColor.text);
       btnFuenf.setBounds(80, 310, 70, 40);
       frmRechner.getContentPane().add(btnFuenf);
       
       //Knopf Sechs (6)
       btnSechs = new JButton("6");
       btnSechs.setForeground(new Color(0, 0, 0));
       btnSechs.addActionListener(new ActionListener() {
           public void actionPerformed(ActionEvent e) {
               NumberPressed(btnSechs.getText());
               
           }
       });
       btnSechs.setFont(new Font("Tahoma", Font.BOLD, 20));
       btnSechs.setBackground(SystemColor.text);
       btnSechs.setBounds(150, 310, 70, 40);
       frmRechner.getContentPane().add(btnSechs);
       
       //Knopf Sieben
       btnSieben = new JButton("7");
       btnSieben.addActionListener(new ActionListener() {
           public void actionPerformed(ActionEvent e) {
               NumberPressed(btnSieben.getText());
               
           }
       });
       btnSieben.setForeground(new Color(0, 0, 0));
       btnSieben.setFont(new Font("Tahoma", Font.BOLD, 20));
       btnSieben.setBackground(SystemColor.text);
       btnSieben.setBounds(10, 270, 70, 40);
       frmRechner.getContentPane().add(btnSieben);
       
       //Knopf Acht (8)
       btnAcht = new JButton("8");
       btnAcht.setForeground(new Color(0, 0, 0));
       btnAcht.addActionListener(new ActionListener() {
           public void actionPerformed(ActionEvent e) {
               NumberPressed(btnAcht.getText());
               
           }
       });
       btnAcht.setFont(new Font("Tahoma", Font.BOLD, 20));
       btnAcht.setBackground(SystemColor.text);
       btnAcht.setBounds(80, 270, 70, 40);
       frmRechner.getContentPane().add(btnAcht);
       
       //Knopf Neun (9)
       btnNeun = new JButton("9");
       btnNeun.setForeground(new Color(0, 0, 0));
       btnNeun.addActionListener(new ActionListener() {
           public void actionPerformed(ActionEvent arg0) {
               NumberPressed(btnNeun.getText());
               
           }
       });
       btnNeun.setFont(new Font("Tahoma", Font.BOLD, 20));
       btnNeun.setBackground(SystemColor.text);
       btnNeun.setBounds(150, 270, 70, 40);
       frmRechner.getContentPane().add(btnNeun);
       
       //Knopf Null (0)
       btnNull = new JButton("0");
       btnNull.addActionListener(new ActionListener() {
           public void actionPerformed(ActionEvent arg0) {
               NumberPressed(btnNull.getText());
               
           }
       });
       btnNull.setFont(new Font("Tahoma", Font.BOLD, 20));
       btnNull.setBackground(SystemColor.text);
       btnNull.setBounds(80, 390, 70, 40);
       frmRechner.getContentPane().add(btnNull);
       
       //Knopf Clear
       JButton btnClear = new JButton("C");
       btnClear.addActionListener(new ActionListener() {
           public void actionPerformed(ActionEvent e) {
               labBack.setText("");
               labFront.setText("");
           }
       });
       btnClear.setForeground(Color.BLACK);
       btnClear.setFont(new Font("Tahoma", Font.PLAIN, 15));
       btnClear.setBackground(SystemColor.controlHighlight);
       btnClear.setBounds(80, 230, 70, 40);
       frmRechner.getContentPane().add(btnClear);
       
       btnBack = new JButton("<--");
       btnBack.addActionListener(new ActionListener() {
           public void actionPerformed(ActionEvent e) {
               int lenght = labFront.getText().length();
               int number = labFront.getText().length() - 1;
               String store;
               
               if(lenght > 0) {
                   StringBuilder back = new StringBuilder(labFront.getText());
                   back.deleteCharAt(number); //Schrittweise -1
                   store = back.toString(); //,,back'' muss wieder in String gewandelt werden
                   labFront.setText(store); //gibt ,,store'' wieder in Text
               }
               
           }
       });
       btnBack.setForeground(Color.BLACK);
       btnBack.setFont(new Font("Tahoma", Font.PLAIN, 15));
       btnBack.setBackground(SystemColor.controlHighlight);
       btnBack.setBounds(150, 230, 70, 40);
       frmRechner.getContentPane().add(btnBack);
       
       
       
       
       //Knopf Vorzeichen ändern (+/-)
       JButton button = new JButton("+/-");
       button.setBackground(SystemColor.controlHighlight);
       button.setBounds(10, 390, 70, 40);
       frmRechner.getContentPane().add(button);
       
       //Knopf Komma setzten (,)
       JButton btnKomma = new JButton(",");
       btnKomma.addActionListener(new ActionListener() {
           public void actionPerformed(ActionEvent arg0) {
               labFront.setText(labFront.getText() + ".");
           }
       });
       btnKomma.setForeground(Color.BLACK);
       btnKomma.setFont(new Font("Tahoma", Font.BOLD, 15));
       btnKomma.setBackground(SystemColor.controlHighlight);
       btnKomma.setBounds(150, 390, 70, 40);
       frmRechner.getContentPane().add(btnKomma);
       
       //Knopf ClearEntry löschen letzter Eingabe(CE)
       JButton btnClearEntry = new JButton("CE");
       btnClearEntry.addActionListener(new ActionListener() {
           public void actionPerformed(ActionEvent arg0) {
               labFront.setText("");
           }
       });
       btnClearEntry.setForeground(Color.BLACK);
       btnClearEntry.setFont(new Font("Tahoma", Font.PLAIN, 15));
       btnClearEntry.setBackground(SystemColor.controlHighlight);
       btnClearEntry.setBounds(10, 230, 70, 40);
       frmRechner.getContentPane().add(btnClearEntry);
       
       labBack = new JLabel("");
       labBack.setFont(new Font("Tahoma", Font.PLAIN, 12));
       labBack.setVerticalAlignment(SwingConstants.TOP);
       labBack.setHorizontalAlignment(SwingConstants.RIGHT);
       labBack.setBounds(0, 54, 304, 67);
       frmRechner.getContentPane().add(labBack);
       
       labFront = new JLabel("");
       labFront.setFont(new Font("Tahoma", Font.PLAIN, 18));
       labFront.setBackground(SystemColor.info);
       labFront.setHorizontalAlignment(SwingConstants.RIGHT);
       labFront.setBounds(0, 70, 304, 104);
       frmRechner.getContentPane().add(labFront);
       
       
       
   }
   public static void main(String[] args) {
       
       EventQueue.invokeLater(new Runnable() {
           public void run() {
               try {
                   Calculator window = new Calculator();
                   window.frmRechner.setVisible(true);
               } catch (Exception e) {
                   e.printStackTrace();
               }
           }
       });
   }
   
}

Vielleicht hab ich vergessen zu sagen, das in der ersten Version nicht auf Punkt-Vor Strich geachtet werden muss. Heißt ein riesen Problem weniger.. Grundsätzlich bräuchte ich nur Hilfe im Zwischenspeichern der Variablen... Das alles erschwert durch die GUI (noch nie zuvor damit gearbeitet, heißt erstes Projekt)

Danke schonmal für die sehr schnellen Antworten, freut mich:)
 

Robat

Top Contributor
Das alles erschwert durch die GUI
Dem eigentlichen Rechenalgorithmus sollte eigentlich egal sein woher die Daten stammen bzw wo sie ausgegeben werden sollen. Du solltest Eingabe/Verarbeitung/Ausgabe strickt von einander trennen - macht sich auch für das Verständnis besser.

Vielleicht hab ich vergessen zu sagen, das in der ersten Version nicht auf Punkt-Vor Strich geachtet werden muss
Dann würde ich dennoch den Weg über einen Parser gehen (siehe Beitrag von @mihe7 ). Warum würdest du jetzt ein Teilfeature implementieren wollen um es später noch mal anders implementieren zu müssen. Dann doch lieber gleich "richtig" machen und später den Parser nur um die Rechenregeln erweitern
 

mihe7

Top Contributor
Das alles erschwert durch die GUI
Nicht nur deswegen trennt man Logik vom UI...

Das UI brauchst Du erstmal gar nicht. Für den Taschenrechner Version 1 reicht ein Modell, das einzelne "Eingaben" verarbeitet. Im ersten Schritt solltest Du mal davon ausgehen, dass Du wirklich Zahlen erhältst, das vereinfacht die Sache etwas.

Das Modell speichert ein Ergebnis und einen Operator. Es hat zwei Invarianten:
1. es gibt immer ein Ergebnis, das den Stand der vergangenen Berechnungen darstellt.
2. es muss ein Operator existieren, bevor das Modell eine Zahl erhalten darf.

Um diese durchzusetzen, fängst Du mit einem Ergebnis 0 und dem "+"-Operator an. Wenn das Modell eine Zahl erhält, muss sichergestellt werden, dass der Operator im Modell gesetzt ist. Dann wird der Operator auf das bisherige Ergebnis und die neu erhaltene Zahl angewendet. Das Resultat stellt das neue Ergebnis des Modells dar. Der Operator wird hinterher entfernt.

Jetzt musst Du Dich halt Schritt für Schritt an das Ziel rantasten.
 

niklas551

Mitglied
Das klingt alles nicht schlecht... und danke nochmal für die antworten!!
Habe das ganze jetzt mit einem Parser versucht
Java:
public String Parsing(String input) {
       List<Integer> zahlen = new ArrayList<>();
       List<Character> operatoren = new ArrayList<>();
       //1.Liste für zahlen, 2.Liste für Operatoren zu speichern
       
       String kurzInput = input.replaceAll(" ", "");
       //Ersetzt im String alle Operatoren mit ";"
       
       kurzInput = input.replaceAll("\\+", ";");
       kurzInput = input.replaceAll("\\-", ";");
       kurzInput = input.replaceAll("\\*", ";");
       kurzInput = input.replaceAll("/", ";");
       try {
       //Erzeugt Array und splittet String input an allen ";"
       String[] zahlenArr = kurzInput.split(";");
       for(int i = 0; i < zahlenArr.length; i++) {   //liest einzelne Zahlen in Array ein
           zahlen.add(Integer.parseInt(zahlenArr[i]));
       }
       }
       catch(Exception ex) {
           labFront.setText("Fehler");
       }
       
       for(int i = 0; i < input.length(); i++) {
           char op = input.charAt(i);
           if(op == '+' || op == '-' || op == '*' || op == '/'){
               operatoren.add(op);
           }
       }
       
       double result = 0;
       
       for(char operator : operatoren) {
           int operatorIndex = operatoren.indexOf(operator);
           double num1 = zahlen.get(operatorIndex);
           double num2 = zahlen.get(operatorIndex + 1);
           
           if(operatorIndex == 0) {
               switch(operator) {
               case '+':
                   result = num1 + num2;
                   break;
               case '-':
                   result = num1 - num2;
                   break;
               case '*':
                   result = num1 * num2;
                   break;
               case '/':
                   result = num1 / num2;
                   break;
               default:
                   result = 0;
                   break;
               }
           }
           else {
               switch(operator) {
               case '+':
                   result += num2;
                   break;
               case '-':
                   result -= num2;
                   break;
               case '*':
                   result *= num2;
                   break;
               case '/':
                   result /= num2;
                   break;
               default:
                   result = 0;
                   break;
               }   
           }   
       }
       
       return Double.toString(result);
       
   }

Funktioniert noch nicht ganz, aber glaube bin auf dem richtigen Weg:)
 

MoxxiManagarm

Top Contributor
Java:
String[] zahlenArr = kurzInput.split("[\\+\\-\\*/]");
split verwendet regular Expression. Das Ersetzen zuvor ist nicht sinnvoll. Muss - wirklich escaped werden? *grübel*

Java:
catch(NumberFormatException ex) {

Bitte fange die genaue Exception ab. In deinem Fall NumberFormatException.

Java:
double left = (operatorIndex != 0) ? result : zahlen.get(operatorIndex);
double right = zahlen.get(operatorIndex + 1);
switch(operator) {
case '+':
    result = left + right;
    break;

Spare dir die Codeverdopplung.

Java:
public String parse(String input) {

Bitte schreibe Methodennamen immer klein.
 

niklas551

Mitglied
WOW, funktioniert direkt besser:) also 2 Zahlen kann ich schon problemlos eingeben. Jetzt wird es natürlich bei mehreren aufeinanderfolgenden Rechnungen schon schwieriger.
Und ja, Methodenname groß hatte ich noch von C# im Kopf *huups*
 
Zuletzt bearbeitet:

niklas551

Mitglied
Aaaalso, meine Überlegung jetzt:
String Eingabe: Bsp.: 10+35-6*3
Ich habe 2 Listen. 1.zList für die Zahlen und 2.oList für die Operatoren
Ich hole dann alle Zahlen und speicher sie in zList und alle Operatoren in oList...
Dann will ich auf die 1.Stelle von oList prüfen ob +-*/ und dementsprechend die 1.Stelle und 2.Stelle von zList miteinander verrechnen. Mit diesem Ergebnis dann weiterrechnen. Heißt prüft 2.Stelle von oList und verrechnet dementsprechend das Ergebnis mit der 3.Stelle von zList usw... So hab ich mir das jetzt mal gedacht, was nicht alzu komplex ist (denke ich/hoffe ich:D), aber ich tu mir da Codemäßig ein wenig schwer
Hier einmal mein Code bisher (natürlich funktioniert er nicht)
Java:
public String parsing(String input) {
        List<Double> zahlen = new ArrayList<Double>();
        List<Character> operatoren = new ArrayList<Character>();
        //1.Liste für zahlen, 2.Liste für Operatoren zu speichern
       
        String kurzInput = input.replaceAll(" ", "");
       
        //Erzeugt Array und splittet String input an allen Operatoren
        String[] zahlenArr = kurzInput.split("[\\+\\-\\*/]");
        for(int i = 0; i < zahlenArr.length; i++) {    //liest einzelne Zahlen in Array ein
            zahlen.add(Double.parseDouble(zahlenArr[i]));
        }
       
        for(int i = 0; i < input.length(); i++) {
            char op = input.charAt(i);
            if(op == '+' || op == '-' || op == '*' || op == '/'){
                operatoren.add(op);

            }
        }
        double ergebnis = 0;
        for(int i= 0; i < zahlenArr.length; i++) {
        for(int j = 0; i <= input.length(); j++)   
            if(operatoren.indexOf(j) == '+') {
                ergebnis = zahlen.indexOf(i) + zahlen.indexOf(i + 1);
                labTest.setText(Double.toString(ergebnis));
            }
            else if(operatoren.indexOf(j) == '-') {
                ergebnis = zahlen.indexOf(i) - zahlen.indexOf(i + 1);
            }
            else if(operatoren.indexOf(j) == '*') {
                ergebnis = zahlen.indexOf(i) * zahlen.indexOf(i + 1);
            }
            else if(operatoren.indexOf(j) == '/') {
                ergebnis = zahlen.indexOf(i) / zahlen.indexOf(i + 1);
            }
       
        }
       
       
       
        return Double.toString(ergebnis);
 

MoxxiManagarm

Top Contributor
@mihe7 Ich bin weiblich ^^

Java:
zahlen.add(Double.parseDouble(zahlenArr[i]));
Die NumberFormatException solltest du schon abfangen oder werfen.

Java:
if(op == '+' || op == '-' || op == '*' || op == '/')
Nichts verkehrt, aber in Hinblick auf spätere weitere Operatoren empfehle ich eher sowas:
Java:
Arrays.asList('+', '-', '*', '/').contains(op)
Deine oder-'Liste' könnte sonst ziemlich lang werden.

Java:
operatoren.indexOf(j)
Sollte das nicht ein List::get sein?

Ich bin noch verwirrt warum du auf einmal 2 Schleifen hast, erkenne das Ziel dahinter nicht und bezweifle, dass das richtig ist. Vorher sah es richtiger aus. Du rechnest nun auch immer mit 2 zahlen aus dem Array und nicht mehr mit dem Vorergebnis.
 

MoxxiManagarm

Top Contributor
Kleines Beispiel wie es aussehen könnte. Allerdings ist das Beispiel nun auch quick&dirty. Bitte entsprechendes Fehlerhandling ergänzen:

Java:
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.DoubleBinaryOperator;
import java.util.stream.Collectors;

public class SimpleExpressionParser {
    private static final Map<Character, DoubleBinaryOperator> OPERATIONS = new HashMap<>();
    static {
        OPERATIONS.put('+', (o1, o2) -> o1 + o2);
        OPERATIONS.put('-', (o1, o2) -> o1 - o2);
        OPERATIONS.put('*', (o1, o2) -> o1 * o2);
        OPERATIONS.put('/', (o1, o2) -> o1 / o2);
    }
 
    public static void main(String... args) {
        String expression = "3+4-6*5";
     
        List<Double> operants = Arrays.stream(expression.split("[\\+\\*\\-/]")) // hier auch keySet verwenden
                .map(o -> Double.parseDouble(o))
                .collect(Collectors.toList());
     
        List<Character> operators = expression.chars()
                .mapToObj(c -> (char)c)
                .filter(c -> OPERATIONS.keySet().contains(c))
                .collect(Collectors.toList());
     
        double result = operants.get(0);
     
        for(int i = 0; i < operators.size(); i++) {
            double nextOperant = operants.get(i + 1);
            char operator = operators.get(i);
         
            result = OPERATIONS.get(operator).applyAsDouble(result, nextOperant);
        }
     
        System.out.println(expression + "=" + result);
    }
}
 
Zuletzt bearbeitet:

niklas551

Mitglied
Okay, erstmal vielen Dank für deine Hilfe!!
Dein Code funktioniert auf alle Fälle schonmal, ich versuch diesen jetzt mal etwas ,,simpler'' umzuschreiben denn vieles habe ich noch nie davon gelesen:D
Aber auf jedenfall eine gute Hilfe auf dem Weg zum Erfolg:)
 

niklas551

Mitglied
Java:
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.DoubleBinaryOperator;
import java.util.stream.Collectors;

public class SimpleExpressionParser {
    private static final Map<Character, DoubleBinaryOperator> OPERATIONS = new HashMap<>();
    static {
        OPERATIONS.put('+', (o1, o2) -> o1 + o2);
        OPERATIONS.put('-', (o1, o2) -> o1 - o2);
        OPERATIONS.put('*', (o1, o2) -> o1 * o2);
        OPERATIONS.put('/', (o1, o2) -> o1 / o2);
    }

    public static void main(String... args) {
        String expression = "3+4-6*5";
   
        List<Double> operants = Arrays.stream(expression.split("[\\+\\*\\-/]")) // hier auch keySet verwenden
                .map(o -> Double.parseDouble(o))
                .collect(Collectors.toList());
   
        List<Character> operators = expression.chars()
                .mapToObj(c -> (char)c)
                .filter(c -> OPERATIONS.keySet().contains(c))
                .collect(Collectors.toList());
   
        double result = operants.get(0);
   
        for(int i = 0; i < operators.size(); i++) {
            double nextOperant = operants.get(i + 1);
            char operator = operators.get(i);
       
            result = OPERATIONS.get(operator).applyAsDouble(result, nextOperant);
        }
   
        System.out.println(expression + "=" + result);
    }
}


Oke, also muss leider gestehen, das mir dein Code eeetwas zu kompliziert ist... Macht für viele sicher Sinn, bin jedoch eher noch ein blutiger Anfänger und versteh das wenig bis gar nichts
 

MoxxiManagarm

Top Contributor
Habs umgeschrieben, aber das Beibehalten der Map empfehle ich weiterhin aufgrund der Erweiterbarkeit durch weitere Operatoren.

Java:
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.DoubleBinaryOperator;

public class SimpleExpressionParser {   
    private static SimpleExpressionParser instance;
       
    private final Map<Character, DoubleBinaryOperator> registeredOperations;
    private final String regex;
   
    private SimpleExpressionParser() {
        registeredOperations = new HashMap<>();
       
        // when adding operations, change here
        registeredOperations.put('+', (o1, o2) -> o1 + o2);
        registeredOperations.put('-', (o1, o2) -> o1 - o2);
        registeredOperations.put('*', (o1, o2) -> o1 * o2);
        registeredOperations.put('/', (o1, o2) -> o1 / o2);
       
        // build regular expression dynamically
        StringBuilder sb = new StringBuilder();
        sb.append("[");
        registeredOperations.keySet().forEach(sb::append);
        sb.append("]");
        regex = sb.toString();
    }
   
    // singleton Pattern
    public static SimpleExpressionParser getInstance() {
        if(instance == null) {
            instance = new SimpleExpressionParser();
        }
       
        return instance;
    }
   
    // the parsing semantic
    public double evaluate(String expression) {
        // retrieve numbers of the expression
        List<Double> numbers = new ArrayList<>();
        for(String token : expression.split(regex)) {
            numbers.add(Double.parseDouble(token));
        }

        // retrieve operators of the expression
        List<Character> operators = new ArrayList<>();
        for(int i = 0; i < expression.length(); i++) {
            char c = expression.charAt(i);
            if(registeredOperations.keySet().contains(c)) {
                operators.add(c);
            }
        }
       
        // calculate
        double result = numbers.get(0);
        for(int i = 0; i < operators.size(); i++) {
            double nextNumber = numbers.get(i + 1);
            char operator = operators.get(i);
           
            result = registeredOperations.get(operator).applyAsDouble(result, nextNumber);
        }
       
        return result;
    }
   
    public static void main(String... args) {
        String expression = "3+4-6*8";
        double result = SimpleExpressionParser.getInstance().evaluate(expression);
       
        System.out.println(expression + "=" + result);
    }
}
 
Zuletzt bearbeitet:

niklas551

Mitglied
okay, hast dein Text anscheinend nochmal geändert, weil er sieht auf jedenfall mehr komplexer aus als gestern. Aber habe jetzt dein vereinfachten Code von gestern und habe diesen mal genommen:)
Jetzt bin ich soweit durch und muss sagen, es läuft;)
Eine einzige Sache, welche mir fehl müsste jedoch noch implementiert werden und zwar, wenn ich 10 + 10 eingebe, dann kein Gleichheitszeichen drücke, sondern nochmal einen Operator um eine weitere Rechnung dazuzurechnen, sollte er jetzt schon das Ergebnis von 10 + 10 ausgeben... Siehe Win10 Taschenrechner.. Im Hintergunde steht die Rechnung, im Vordergrund die Teilergebnisse, sowie das gesame Ergebnis wenn man das Gleichheitszeichen betätigt
Gruß und nochmals ein dickes Dankeschön!:)
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
Exelsior JavaFX Taschenrechner mit FX AWT, Swing, JavaFX & SWT 6
melaniemueller Taschenrechner JavaFX AWT, Swing, JavaFX & SWT 4
N JavaFX Einfacher Taschenrechner mit Scene Builder und Java FX AWT, Swing, JavaFX & SWT 0
thor_norsk Taschenrechner AWT, Swing, JavaFX & SWT 8
melaniemueller JavaFX Taschenrechner mit SceneBuilder AWT, Swing, JavaFX & SWT 12
K JavaFX Taschenrechner textField auf 10stellen begrenzen AWT, Swing, JavaFX & SWT 26
L JavaFX javafx.fxml.LoadException bei einem Taschenrechner AWT, Swing, JavaFX & SWT 5
N Swing Taschenrechner GUI AWT, Swing, JavaFX & SWT 13
B Probleme Action Listener Taschenrechner AWT, Swing, JavaFX & SWT 27
O JavaFX mini Taschenrechner! AWT, Swing, JavaFX & SWT 35
A JavaFX Sehr viele Exceptions bei Taschenrechner mit JavaFx AWT, Swing, JavaFX & SWT 2
K Taschenrechner mit GUI AWT, Swing, JavaFX & SWT 2
L Event Handling Gui für Taschenrechner AWT, Swing, JavaFX & SWT 27
H Swing Taschenrechner GUI AWT, Swing, JavaFX & SWT 5
M Taschenrechner AWT, Swing, JavaFX & SWT 21
T Swing Taschenrechner AWT, Swing, JavaFX & SWT 2
M AWT Java-Taschenrechner, wie Stack richtig verwenden? AWT, Swing, JavaFX & SWT 14
C Grafik Taschenrechner AWT, Swing, JavaFX & SWT 5
H Taschenrechner Coding Erklärung AWT, Swing, JavaFX & SWT 2
Jats Hilfe bei FocusListener für Taschenrechner AWT, Swing, JavaFX & SWT 4
B Taschenrechner mit ComboBox AWT, Swing, JavaFX & SWT 7
S AWT Probleme mit Taschenrechner AWT, Swing, JavaFX & SWT 9
V Bitte um Hilfe bei nem Taschenrechner AWT, Swing, JavaFX & SWT 8
C Taschenrechner in Java AWT, Swing, JavaFX & SWT 7
M MouseEvent JButton Taschenrechner AWT, Swing, JavaFX & SWT 5
K Java-Taschenrechner AWT, Swing, JavaFX & SWT 1
L Taschenrechner mit Klammern AWT, Swing, JavaFX & SWT 11
H Taschenrechner AWT, Swing, JavaFX & SWT 5
G Taschenrechner-Problem AWT, Swing, JavaFX & SWT 2
G Ikonli in Fat-Jar mit mehreren Icon-Packs einbinden AWT, Swing, JavaFX & SWT 5
F Zeile in mehreren Jtables bei Selektion markieren AWT, Swing, JavaFX & SWT 11
K JavaFX Resizing-Problem beim BorderLayout (Center Component) beim Arbeiten mit mehreren FXMLs AWT, Swing, JavaFX & SWT 2
P JavaFx - Progressbar - Füllen mittels mehreren Tasks AWT, Swing, JavaFX & SWT 0
O Basics - Anwendung erstellen mit mehreren Szenen AWT, Swing, JavaFX & SWT 1
M Swing MVC-Pattern - View mit mehreren Models AWT, Swing, JavaFX & SWT 5
B JavaFX PrinterJob mit mehreren Seiten AWT, Swing, JavaFX & SWT 0
T JavaFX Label mit mehreren Images AWT, Swing, JavaFX & SWT 11
R KeyListener in mehreren Panels AWT, Swing, JavaFX & SWT 5
M Ein Element in mehreren JList selektieren AWT, Swing, JavaFX & SWT 5
W Swing JPanel nur einmal nach mehreren Änderungen neu zeichnen AWT, Swing, JavaFX & SWT 1
S JComboBox mit mehreren Spalten? AWT, Swing, JavaFX & SWT 6
K Swing Keine Reaktion auf Tastatureingaben bei mehreren Buttons??? AWT, Swing, JavaFX & SWT 4
M Swing MVC mit mehreren Klassen AWT, Swing, JavaFX & SWT 2
J JavaFX eine Art Tabelle, jedoch mit mehreren Zeilen AWT, Swing, JavaFX & SWT 2
K Swing Klassenstruktur mit mehreren JPanels AWT, Swing, JavaFX & SWT 3
M Applikation mit mehreren Scenes AWT, Swing, JavaFX & SWT 5
F Swing JAVA GUI Übergabe von Werten zwischen mehreren Fenstern/Klassen AWT, Swing, JavaFX & SWT 10
A JButton - Klicks zählen auf mehreren Buttons AWT, Swing, JavaFX & SWT 2
J Mit mehreren in Objekten in JFrame printen? AWT, Swing, JavaFX & SWT 8
P Liste mit Icons und mehreren Spalten AWT, Swing, JavaFX & SWT 7
B Swing Formular mit mehreren Elementen - wie die ActionListener-Verarbeitung lösen? AWT, Swing, JavaFX & SWT 2
S Shape erstellen der aus mehreren Elementen besteht..? AWT, Swing, JavaFX & SWT 3
F Tablemodel zu mehreren Tabellen AWT, Swing, JavaFX & SWT 6
T Sichtbarmachen von Objekten auf mehreren JPanels AWT, Swing, JavaFX & SWT 2
DamienX Swing Component auf mehreren Containern AWT, Swing, JavaFX & SWT 2
B Swing JFormattedTextField auf mehreren JPanels in einer JTabbedPane AWT, Swing, JavaFX & SWT 3
M In Jlist auf Änderungen von mehreren JLabels reagieren AWT, Swing, JavaFX & SWT 3
E JTable nach mehreren Spalten sortieren AWT, Swing, JavaFX & SWT 14
B SWT SWT Tree mit mehreren Spalten AWT, Swing, JavaFX & SWT 3
W GUI in mehreren Threads AWT, Swing, JavaFX & SWT 5
J Swing JComboBox mit mehreren Spalten AWT, Swing, JavaFX & SWT 4
T Auf Ende von mehreren Threads warten, ohne den EDT zu blockieren AWT, Swing, JavaFX & SWT 1
J SWING Fenster mit mehreren JPanels (dank JLayeredPane) AWT, Swing, JavaFX & SWT 19
T Swing KeyListener mit mehreren Objekten AWT, Swing, JavaFX & SWT 2
G Verliere Referenz von Toolbar bei mehreren Fenster AWT, Swing, JavaFX & SWT 3
M MVC: Grundidee verstanden aber was machen mit mehreren Model AWT, Swing, JavaFX & SWT 2
R Daten in JTable in mehreren Zeilen darstellen AWT, Swing, JavaFX & SWT 11
G JDialog mit mehreren Elementen! AWT, Swing, JavaFX & SWT 5
G Ein Frame mit mehreren austauschbaren Panels AWT, Swing, JavaFX & SWT 3
S JTable audrucken, aber mit mehreren Footers und Headers AWT, Swing, JavaFX & SWT 2
O Zwischen mehreren Bildern wechseln AWT, Swing, JavaFX & SWT 6
S Enter in JLabel - oder: JTabbedPane mit mehreren JLabel AWT, Swing, JavaFX & SWT 3
I Arbeiten mit mehreren Fenstern AWT, Swing, JavaFX & SWT 4
H jar-archive mit mehreren Klassen erstellen AWT, Swing, JavaFX & SWT 3
G Organisation Anwendung mit mehreren Eingabedialogen AWT, Swing, JavaFX & SWT 3
L Probleme mit mehreren Canvas: Überlagerungseffekte? AWT, Swing, JavaFX & SWT 5
N JComboBox mit mehreren Spalten AWT, Swing, JavaFX & SWT 21
Q Auf mehreren JPanels Bilder zeichnen. AWT, Swing, JavaFX & SWT 5
T Swing: MainForm mit mehreren Tabs AWT, Swing, JavaFX & SWT 6
K Spaltenbreite von mehreren Tabellen gleichzeitig verändern AWT, Swing, JavaFX & SWT 3
H JTable Text aus mehreren Zellen in einer Spalte kopieren? AWT, Swing, JavaFX & SWT 3
R Navigieren zwischen mehreren Fenstern AWT, Swing, JavaFX & SWT 7
U Anwendung mit mehreren "Fenstern" AWT, Swing, JavaFX & SWT 4
M JDialog mit mehreren Eingabenfeldern? AWT, Swing, JavaFX & SWT 5
M jtabbedpane mit mehreren layoutmanagern? AWT, Swing, JavaFX & SWT 2
V Werte mehreren Checkboxes zuweisen AWT, Swing, JavaFX & SWT 3
T JList mit mehreren spalten AWT, Swing, JavaFX & SWT 2
M Mit mehreren Panels arbeiten AWT, Swing, JavaFX & SWT 2
A JFrame mit mehreren Panels AWT, Swing, JavaFX & SWT 10
P JTable nach mehreren Spalten sortieren AWT, Swing, JavaFX & SWT 15
V JTable mit mehreren Componenten in einer Spalte ? AWT, Swing, JavaFX & SWT 6
M Dialog mit mehreren Komponenten AWT, Swing, JavaFX & SWT 4
N Checkbox mit mehreren Strings belegen? AWT, Swing, JavaFX & SWT 6
D iText Rechnungen AWT, Swing, JavaFX & SWT 12

Ähnliche Java Themen

Neue Themen


Oben