[Java] Rechner programmieren

Dieses Thema im Forum "Programmierung & Entwicklung" wurde erstellt von FLiFLu, 1. Dezember 2009 .

  1. 1. Dezember 2009
    Rechner programmieren

    Hallo jungs,

    ich bin noch ein ziehmlicher Anfänger in Java und wende mich deshalb an euch...

    ich soll ein Rechner programmieren hier die Aufgabenstellung:

    "Schreiben Sie die ein Programm, welches als Eingabe einen mathematischen Ausdruck
    einliest und anschlißend das Ergebnis ausgibt:
    Das Programm ist so zu realisieren, dass maximal 4 Operatoren bzw. 5 Operanden
    eingegeben werden können. Die richtige Syntax muss vor der Berechnung geprüft werden.
    <Variable>=<operand><operator><operand><operator><operand> ..... usw."

    nun ja ich hab verstanden was ich tun soll nur gleich meine erste frage wie lese ich da das ein ich sag

    System.out.println("Bitte geben sie ihre Rechnung ein: ");

    ja und dann was schreib ich dann in mein code rein damit er weiss das das die zeichenkette ist?? thx shconmal bw drinne!
     
  2. 1. Dezember 2009
    AW: Rechner programmieren

    Die Eingabe ist eigentlich ganz einfach:
    Code:
    import java.util.Scanner;
    
    Scanner tastatur = new Scanner(System.in);
    String text;
    
    text=tastatur.nextLine();
    
     
  3. 1. Dezember 2009
    AW: Rechner programmieren

    Speichere die komplette Eingabe in einem String ab.
    Ich vermute, dass ihr mit Regex noch nicht gearbeitet habt und es daher nicht verlangt ist.
    Daher würde ich Zeichenweise den eingegeben String durchgehen und kontrollieren ob es eine zusammenhängede Zahl ist oder ein Operator.

    Code:
    String myString = "xyz";
    char [] myCharArray = myString.toCharArray ();
     
  4. 1. Dezember 2009
    AW: Rechner programmieren

    was zum teufel....!!! ich hab ja schon viele möglichkeiten gesehen tastatureingaben einzulesen aber das hier is mal richtig geil xD muss ich mir mal anguckn ^^
     
  5. 1. Dezember 2009
    AW: Rechner programmieren

    Ich hab mir genau das gleiche gedacht! Ich kenn auch nur diese Variante (die auch übrigens normalerweise in Java Vorlesungen beigebracht wird):
    Code:
    BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
    String input = reader.readLine();
    
     
  6. 1. Dezember 2009
    AW: Rechner programmieren

    Mir wurde die Variante oben in meiner Vorlesung beigebracht und die finde ich auch viel schöner als das was cr9wd geposted hat.
     
  7. 2. Dezember 2009
    AW: Rechner programmieren

    ich find die mit dem BufferedReader schöner und besser da man da sofort weiss das die eingabe gepuffert wird. unter scanner kann man sich meiner meinung nach nichts vorstellen
     
  8. 3. Dezember 2009
    AW: Rechner programmieren

    Gibt doch keinen nennenswerten Unterschied, außer dass beim Scanner noch ein bisschen mehr gekapselt wird. Also suum cuique. Völlig Lattenzaun, was man benutzt.

    Um mit deinem Eingabestring weiterzuarbeiten solltest du dir einmal die StringTokenizer-Klasse anschauen.

    Wie komplex soll der Rechner denn werden? Sollen auch noch gewisse Regeln wie "Punkt- vor Strichrechnung" beachtet werden? Wenn dem so ist, musst du noch ne ganze Runde weitergehen.
     
  9. 4. Dezember 2009
    AW: Rechner programmieren

    http://sourceforge.net/projects/jep/ kostenloas
    http://www.bmtmicro.com/BMTCatalog/win/jbcparser.html kostet a weng

    typisch java... 100~ class-files ^^
    bei ner c++ variante bekommst du nen compiler incl. bytecode-interpreter :lol:

    aber wie dem auch sei -> damit kannst du mathematische ausdrücke parsen
     
  10. 7. Dezember 2009
    AW: Rechner programmieren

    Ich hab in C++ mal sowas gemacht, viell hilfts dir ja weiter.. zu java umändern is ja nich schwer

    // Start des Hauptprogrammes
    main()
    {
    // Variablen deklarieren
    char funktion; // Operator der Aufgabe
    int zahl1, zahl2; //int oder double wie auch immer

    // Aufgabe einlesen
    cout << "Bitte eine Aufgabe eingeben: ";
    cin >> zahl1 >> funktion >> zahl2;

    // Aufgabe auswerten und Ergebnis ausgeben
    cout << "Das Ergebnis ist ";

    switch (funktion)
    {
    case '+':
    cout << zahl1 + zahl2;
    break;
    case '-':
    cout << zahl1 - zahl2;
    break;
    case '*':
    cout << zahl1 * zahl2;
    break;
    case '/':
    cout << zahl1 / zahl2;
    break;
    default:
    cout << "nicht berechenbar, weil der Rechenoperator nicht unterstützt wird.";
    break;
    }

    cout << endl;
    }

    Nur als Beispiel, kannst ja nun an deine Aufgabenstellung anpassen...

    Good Luck
     
  11. 7. Dezember 2009
    AW: Rechner programmieren

    falls es dir hilft, hier ein math-parser in php: (beherrscht punkt vor strich, klammern und funktionen ^^)
    hab ich eben selbst programmiert in ~2std -> siehst also das es im grunde einfach ist.

    array_shift() is quasi die php-funktion für nen fifo-stack

    PHP:
    <? php

    define
    ( 'SIMPLE_MATH_NUMBER' ,          0 );
    define ( 'SIMPLE_MATH_TIMES' ,          1 );
    define ( 'SIMPLE_MATH_DIV' ,              2 );
    define ( 'SIMPLE_MATH_PLUS' ,             3 );
    define ( 'SIMPLE_MATH_MINUS' ,          4 );
    define ( 'SIMPLE_MATH_PAREN_OPEN' ,      5 );
    define ( 'SIMPLE_MATH_PAREN_CLOSE' ,      6 );
    define ( 'SIMPLE_MATH_FUNCTION' ,         7 );


    function  simple_math_reduce ( $expr ) {
        
    $tokens  simple_math_tokenize ( $expr );
        
    simple_math_reduce_td ( $tokens );
        return 
    simple_math_reduce_as ( $tokens );
    }


    function  simple_math_pop_number (array & $tokens $prefix  true ) {
        
        
    $next  array_shift ( $tokens );
        if(
    $next  ===  null  ||  $next [ 'type' ] !==  SIMPLE_MATH_NUMBER ) {
            switch(
    $next [ 'type' ]) {
                case 
    SIMPLE_MATH_PAREN_OPEN :
                    return 
    simple_math_reduce_paren ( $tokens );
                case 
    SIMPLE_MATH_FUNCTION :
                    return 
    simple_math_exec_function ( $next [ 'value' ],  $tokens );
                case 
    SIMPLE_MATH_PLUS //unary
                    
    if( $prefix  ===  true )
                        return 
    simple_math_pop_number ( $tokens false );
                    break;
                case 
    SIMPLE_MATH_MINUS //unary
                    
    if( $prefix  ===  true )
                        return -
    simple_math_pop_number ( $tokens false );
                    break;
            }
            
            exit(
    'syntax fehler. nummer, "(" ausdruck ")" oder funktion erwartet' );
        }
        
        return 
    $next [ 'value' ];
    }


    function  simple_math_exec_function ( $func , array & $tokens ) {
        
    $next  array_shift ( $tokens );
        if(
    $next  ===  null  ||  $next [ 'type' ] !==  SIMPLE_MATH_PAREN_OPEN )
            exit(
    'syntax fehler, "(" ausdruck ")" erwartet, "'  $next [ 'value' ] .  '" gefunden' );
        
        unset(
    $next );
        
    $number  simple_math_reduce_paren ( $tokens );
        
        switch(
    $func ) {
            case 
    'sqrt' :
                return 
    sqrt ( $number );
            case 
    'log' :
                return 
    log ( $number );
            case 
    'log10' :
                return 
    log10 ( $number );
            case 
    'abs' :
                return 
    abs ( $number );
            default: 
                exit(
    'unbekannte funktion "'  $func  '"' );
        }
    }


    function  simple_math_reduce_paren (array & $tokens ) {
        
    $inner  = array();
        while((
    $token  array_shift ( $tokens )) !==  null ) {
            if(
    $token [ 'type' ] ===  SIMPLE_MATH_PAREN_CLOSE ) {
                
    simple_math_reduce_td ( $inner );
                return 
    simple_math_reduce_as ( $inner );
            }
            
            if(
    $token [ 'type' ] ===  SIMPLE_MATH_FUNCTION )
                
    $token  = array( 'type'  =>  SIMPLE_MATH_NUMBER 'value'  =>  simple_math_exec_function ( $token [ 'value' ],  $tokens ));
            
            if(
    $token [ 'type' ] ===  SIMPLE_MATH_PAREN_OPEN )
                
    $token  = array( 'type'   =>  SIMPLE_MATH_NUMBER 'value'  =>  simple_math_reduce_paren ( $tokens ));
            
            
    $inner [] =  $token ;
        }
        
        exit(
    'syntax fehler. ")" erwartet.' );
    }


    function  simple_math_reduce_td (array & $tokens ) {
        
    $result      simple_math_pop_number ( $tokens );
        
    $new_stack   = array();
        while((
    $token  array_shift ( $tokens )) !==  null ) {
            if(
    $token [ 'type' ] ===  SIMPLE_MATH_NUMBER )
                exit(
    'syntax fehler. operator erwartet, "'  $token [ 'value' ] .  '" gefunden.' );
            
            
    $finish  false ;
            switch(
    $token [ 'type' ]) {
                case 
    SIMPLE_MATH_TIMES :
                    
    $result  *=  simple_math_pop_number ( $tokens );
                    break;
                case 
    SIMPLE_MATH_DIV :
                    
    $number  simple_math_pop_number ( $tokens );
                    if(
    $number  ==  0 ) exit( 'division durch null ('  $result  ' : '  $number  ')' );
                    
    $result  /=  $number ;
                    break;
                default:
                    
    $new_stack [] = array( 'type'  =>  SIMPLE_MATH_NUMBER 'value'  =>  $result );
                    
    $new_stack [] =  $token ;
                    
    $result  simple_math_pop_number ( $tokens );
            }
        }
        
        
    $new_stack [] = array( 'type'  =>  SIMPLE_MATH_NUMBER 'value'  =>  $result );
        
    $tokens  $new_stack ;
    }


    function  simple_math_reduce_as (array & $tokens ) {    
        
    $result  simple_math_pop_number ( $tokens );
        while((
    $token  array_shift ( $tokens )) !==  null ) {
            if(
    $token [ 'type' ] ===  SIMPLE_MATH_NUMBER )
                exit(
    'syntax fehler. operator erwartet, "'  $token [ 'value' ] .  '" gefunden.' );
            
            switch(
    $token [ 'type' ]) {
                case 
    SIMPLE_MATH_PLUS :
                    
    $result  +=  simple_math_pop_number ( $tokens );
                    break;
                case 
    SIMPLE_MATH_MINUS :
                    
    $result  -=  simple_math_pop_number ( $tokens );
                    break;
                default: 
                    exit(
    'syntax fehler. der operator "'  $token [ 'value' ] .  '" ist an dieser stelle nicht zulässig' );
            }
        }
        
        return 
    $result ;
    }    


    function  simple_math_tokenize ( $expr ) {
        
    $tokens  = array();
        
    $stack   = array();
        
    preg_match_all ( '~((?:[0-9]*\.[0-9]+|[0-9]+)|[:\*\+\-/\(\)]|[a-z0-9]+)~' $expr $tokens );
        for(
    $i  0 $l  count ( $tokens [ 1 ]);  $i  $l ; ++ $i ) {
            switch(
    $tokens [ 1 ][ $i ]) {
                case 
    '+' :
                    
    $type  SIMPLE_MATH_PLUS ;
                    break;
                case 
    '-' :
                    
    $type  SIMPLE_MATH_MINUS ;
                    break;
                case 
    '*' :
                    
    $type  SIMPLE_MATH_TIMES ;
                    break;
                case 
    ':' :
                case 
    '/' :
                    
    $type  SIMPLE_MATH_DIV ;
                    break;
                case 
    '(' :
                    
    $type  SIMPLE_MATH_PAREN_OPEN ;
                    break;
                case 
    ')' :
                    
    $type  SIMPLE_MATH_PAREN_CLOSE ;
                    break;
                default:
                    if(
    is_numeric ( $tokens [ 1 ][ $i ])) {
                        
    $tokens [ 1 ][ $i ]  =  floatval ( $tokens [ 1 ][ $i ]);
                        
    $type  SIMPLE_MATH_NUMBER ;
                    } else {
                        
    $type  SIMPLE_MATH_FUNCTION ;
                    }
            }
            
            
    $stack [] = array( 'type'  =>  $type 'value'  =>  $tokens [ 1 ][ $i ]);
        }
        
        return 
    $stack ;
     
  12. 9. Dezember 2009
    AW: Rechner programmieren

    Hab mal vor einiger Zeit sowas ähnliches gelöst, muss man halt nur für mehrere Operationen anpassen, bzw. weiß ich nicht ob du die einzelnen Operanden und Operatoren getrennt per Leerzeichen bekommst oder nicht, denn wenn nicht müsstest du von der Konsole einlesen wie schon oben beschrieben wenn nicht, gehts mit Änderungen so wie unten im Code:

    PHP:
    import java . util . Scanner ;
    class 
    Calculator  {
       public static 
    void main  String  []  args  ) {      
          
    Scanner einlesen  = new  Scanner ( System . in );
          
          
    int zahl_a zahl_b ;             //Variablen deklarationen
          
    String operator ;
          
    int erg = 0 ;
          
    int ok = 0 ;
         
          try{
              
    zahl_a  einlesen . nextInt ();      //Von Konsole einlesen
              
    zahl_b  einlesen . nextInt ();
              
    operator  einlesen . next ();
        
                  if(
    operator . charAt ( 0 )== '+' ){  erg = zahl_a + zahl_b ok = 1 ;}
                  if(
    operator . charAt ( 0 )== '-' ){  erg = zahl_a - zahl_b ok = 1 ;}
                  if(
    operator . charAt ( 0 )== '/' ){  erg = zahl_a / zahl_b ok = 1 ;}
                  if(
    operator . charAt ( 0 )== '*' ){  erg = zahl_a * zahl_b ok = 1 ;}
              
                  if(
    ok == 0 ){ 
                      
    System . out . println ( "FALSCHE EINGABE" );
                  }
                  else{
                      
    System . out . println ( erg );
                  }
         }                    
    //Fehlerausgabe
         
    catch( Exception e ){  System . out . println ( "FALSCHE EINGABE" ); }
       }
    }
    s3ns3 :]
     
  13. 10. Dezember 2009
    Zuletzt von einem Moderator bearbeitet: 15. April 2017
    AW: Rechner programmieren

    so hier in java programmiert: (bez. [Java] Rechner programmieren - RR:Board)

    Code:
    import java.util.NoSuchElementException;
    import java.util.LinkedList;
    import java.util.ListIterator;
    import java.util.HashMap;
    import java.util.regex.*;
    
    /**
    * token-class
    *
    * stores: double number (if available)
    * String value
    * int type
    */
    class Token 
    {
     public double number;
     public int type;
     public String value;
     
     /**
     * initializes a number-token
     *
     * @param double number
     */
     public Token(double number)
     {
     this.number = number;
     this.type = 0;
     this.value = new StringBuilder().append(number).toString();
     }
     
     /**
     * initializes a operator- or function-token
     *
     * @param int type
     * @param String value
     */
     public Token(int type, String value)
     {
     this.number = 0;
     this.type = type;
     this.value = value;
     }
    };
    
    /**
    * callback-class
    */
    class Callback
    {
     public double exec(double number)
     {
     return .0;
     }
    };
    
    public class Parser
    { 
     //functiontable
     public HashMap functions = new HashMap();
     
     /**
     * main-method
     */
     public static void main(String args[])
     {
     if(args.length > 0) {
     Parser p = new Parser();
     System.out.println("result is: " + p.reduce(args[0]));
     }
     }
     
     /**
     * constructor
     */
     public Parser() 
     {
     //default functions
     this.functions.put("abs", new Callback() { public double exec(double number) { return Math.abs(number); } });
     this.functions.put("sqrt", new Callback() { public double exec(double number) { return Math.sqrt(number); } });
     this.functions.put("log", new Callback() { public double exec(double number) { return Math.log(number); } });
     }
     
     /**
     * tokenizes a expr
     *
     * @param String expr
     * @param LinkedList<Token> tokens
     * @return void
     */
     protected void tokenize(String expr, LinkedList<Token> tokens)
     {
     //tokenize-pattern
     Matcher match = Pattern.compile("[0-9]+\\.[0-9]+|[0-9]+|[:\\*\\+\\-/\\(\\)]|[a-z0-9]+").matcher(expr);
     //number-pattern
     Pattern numeric = Pattern.compile("[0-9]+\\.[0-9]+|[0-9]+");
     
     while(match.find()) {
     String token = expr.substring(match.start(), match.end());
     switch(token.charAt(0)) {
     case '+':
     tokens.add(new Token(1, "+"));
     break;
     case '-':
     tokens.add(new Token(2, "-"));
     break;
     case '*':
     tokens.add(new Token(3, "*"));
     break;
     case ':':
     case '/':
     tokens.add(new Token(4, "/"));
     break;
     case '(':
     tokens.add(new Token(5, "("));
     break;
     case ')':
     tokens.add(new Token(6, ")"));
     break;
     default:
     if(numeric.matcher(token).matches()) {
     tokens.add(new Token(Double.valueOf(token)));
     break;
     }
     
     tokens.add(new Token(7, token));
     }
     }
     
     
     }
     
     /**
     * prints a error-message and exits the application
     *
     * @param String error
     * @return void
     */
     protected void exitError(String error)
     {
     System.out.println(error);
     System.exit(1);
     }
     
     /**
     * executes a function and returns the result
     *
     * @param String func
     * @param LinkedList<Token> tokens
     * @return double
     */
     protected double execFunction(String func, LinkedList<Token> tokens)
     {
     if(((Token) tokens.remove(0)).type != 5)
     this.exitError("syntax error, expecting \"(\" after function-call " + func);
     
     double number = this.reduceParen(tokens);
     if(!this.functions.containsKey(func))
     this.exitError("undefined function " + func);
     
     return ((Callback) this.functions.get(func)).exec(number);
     }
     
     /**
     * parses stuff between ( ) to double
     *
     * @param LinkedList<Token> tokens
     * @return double
     */
     protected double reduceParen(LinkedList<Token> tokens)
     {
     LinkedList<Token> inner = new LinkedList<Token>();
     ListIterator i = tokens.listIterator();
     
     while(i.hasNext()) {
     Token token = (Token) tokens.remove(i.nextIndex());
     
     if(token.type == 6)
     return this.reduce(inner);
     else if(token.type == 5)
     token = new Token(this.reduceParen(tokens));
     else if(token.type == 7)
     token = new Token(this.execFunction(token.value, tokens));
     
     inner.add(token);
     }
     
     this.exitError("unexpected END, missing \")\"");
     return 0;
     }
     
     /**
     * pops a number from stack - unary "+" or "-" is not allowed!
     *
     * @param LinkedList<Token> tokens
     * @param boolean ...
     * @return double
     */
     protected double popNumber(LinkedList<Token> tokens, boolean _)
     {
     Token next;
     try {
     next = (Token) tokens.remove(0);
     } catch(NoSuchElementException e) {
     this.exitError("unepxected END, expecting number, function or ( expression )");
     return 0;
     }
     
     if(next.type != 0) {
     switch(next.type) {
     case 5:
     return this.reduceParen(tokens);
     case 7:
     return this.execFunction(next.value, tokens);
     default:
     this.exitError("unexpected " + next.value + ", expecting number, function or ( expresssion )");
     }
     }
     
     return next.number;
     }
     
     /**
     * pops a number from stack
     *
     * @param LinkedList<Token> tokens
     * @return double
     */
     protected double popNumber(LinkedList<Token> tokens)
     {
     Token next;
     
     try {
     next = (Token) tokens.remove(0);
     } catch(NoSuchElementException e) {
     this.exitError("unexpected END, expecting number, function or ( expression )");
     return 0;
     }
     
     if(next.type != 0) {
     switch(next.type) {
     case 5:
     return this.reduceParen(tokens);
     case 7:
     return this.execFunction(next.value, tokens);
     case 1:
     return this.popNumber(tokens, false);
     case 2:
     return -this.popNumber(tokens, false);
     default:
     this.exitError("unexpected token " + next.value + ", expecting number, function or ( expression )");
     }
     }
     
     return next.number;
     }
     
     /**
     * reduces expr*expr or expr/expr
     *
     * @param LinkedList<Token> tokens
     * @return void
     */
     protected LinkedList<Token> reduceTimesDiv(LinkedList<Token> tokens)
     {
     double result = this.popNumber(tokens);
     LinkedList<Token> newStack = new LinkedList<Token>();
     ListIterator i = tokens.listIterator();
     
     while(i.hasNext()) {
     Token token = (Token) tokens.remove(i.nextIndex());
     
     if(token.type == 0)
     this.exitError("unexpected number " + token.value + ", expecting operator");
     
     switch(token.type) {
     case 3:
     result *= this.popNumber(tokens);
     break;
     case 4:
     result /= this.popNumber(tokens);
     break;
     default:
     newStack.add(new Token(result));
     newStack.add(token);
     result = this.popNumber(tokens);
     break;
     }
     }
     
     newStack.add(new Token(result));
     return newStack;
     }
     
     /**
     * reduces expr+expr or expr-expr
     *
     * @param LinkedList<Token> tokens
     * @return double
     */
     double reduceAddSub(LinkedList<Token> tokens)
     {
     double result = this.popNumber(tokens);
     ListIterator i = tokens.listIterator();
     
     while(i.hasNext()) {
     Token token = (Token) tokens.remove(i.nextIndex());
     
     if(token.type == 0)
     this.exitError("unepxected number, expecting operator");
     
     switch(token.type) {
     case 1:
     result += this.popNumber(tokens);
     break;
     case 2:
     result -= this.popNumber(tokens);
     break;
     default:
     this.exitError("invalid expression");
     }
     }
     
     return result;
     }
     
     /**
     * compiles a expr to double
     *
     * @param String expr
     * @return double
     */
     public double reduce(String expr)
     {
     LinkedList<Token> tokens = new LinkedList<Token>();
     this.tokenize(expr, tokens);
     tokens = this.reduceTimesDiv(tokens);
     return this.reduceAddSub(tokens);
     }
     
     /**
     * compiles a stack of Token's to double
     *
     * @param LinkedList<Token> tokens
     * @return double
     */
     public double reduce(LinkedList<Token> tokens)
     {
     tokens = this.reduceTimesDiv(tokens);
     return this.reduceAddSub(tokens);
     }
    };
    bytecode gibts hier
     
  14. Video Script

    Videos zum Themenbereich

    * gefundene Videos auf YouTube, anhand der Überschrift.