Code Java du sujet du logiciel de calcul scientifique.

/*
 * Copyright (c) Régis Clouard
 * ENSICAEN, École publique d'ingénieurs et centres de recherche, Caen, FRANCE.
 * https://www.ensicaen.fr
 *
 * This file is licenced under the MIT License.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
package fr.ensicaen.gl2a;

import java.util.Iterator;
import java.util.NoSuchElementException;

/**
 * TP Calcul scientifique.
 */
public class ScientificCalculus {

    public static void main( String args[] ) {
        System.out.println("Construction de l'expression: (5-x) * (3+4)");
        ArithmeticExpression expression = new Mult(new Sub(new Constante(5), new Variable("x")),
                new Plus(new Constante(3), new Constante(4)));
        System.out.println("L'evaluation pour (x=4). Attendu : 7. Calculé : " + expression.accept(new Evaluation(4)) + ")");

        System.out.println("Elements de l'expression dans l'ordre infixe :");
        for (ArithmeticExpression a : expression) {
            System.out.println("   " + a);
        }
    }
}

/**
 * Patron Composite.
 */
abstract class ArithmeticExpression implements Iterable {
    public abstract Object accept( Visitor v );
}

final class Constante extends ArithmeticExpression {
    private final double _value;

    public Constante( int value ) {
        _value = value;
    }

    double getValue() {
        return _value;
    }

    @Override
    public Object accept( Visitor v ) {
        return v.visite(this);
    }

    @Override
    public Iterator iterator() {
        return new IterateurSimple(this);
    }

    @Override
    public String toString() {
        return "" + _value;
    }
}

final class Variable extends ArithmeticExpression {
    private final String _name;

    public Variable( String name ) {
        _name = name;
    }

    String getName() {
        return _name;
    }

    @Override
    public Object accept( Visitor v ) {
        return v.visite(this);
    }

    @Override
    public Iterator iterator() {
        return new IterateurSimple(this);
    }

    @Override
    public String toString() {
        return getName();
    }
}

abstract class BinaryOperator extends ArithmeticExpression {
    private final ArithmeticExpression _operande1;
    private final ArithmeticExpression _operande2;
    //ou ListVector _operandes; pour les opérateur naires.

    public BinaryOperator( ArithmeticExpression operande1, ArithmeticExpression operande2 ) {
        _operande1 = operande1;
        _operande2 = operande2;
    }

    public ArithmeticExpression getOperande1() {
        return _operande1;
    }

    public ArithmeticExpression getOperande2() {
        return _operande2;
    }
}

final class Plus extends BinaryOperator {
    public Plus( ArithmeticExpression operande1, ArithmeticExpression operande2 ) {
        super(operande1, operande2);
    }

    @Override
    public Object accept( Visitor v ) {
        return v.visite(this);
    }

    @Override
    public Iterator iterator() {
        return new IterateurComplexe(this);
    }
}

final class Sub extends BinaryOperator {
    public Sub( ArithmeticExpression operande1, ArithmeticExpression operande2 ) {
        super(operande1, operande2);
    }

    @Override
    public Object accept( Visitor v ) {
        return v.visite(this);
    }

    @Override
    public Iterator iterator() {
        return new IterateurComplexe(this);
    }
}

final class Mult extends BinaryOperator {
    public Mult( ArithmeticExpression operande1, ArithmeticExpression operande2 ) {
        super(operande1, operande2);
    }

    @Override
    public Object accept( Visitor v ) {
        return v.visite(this);
    }

    @Override
    public Iterator iterator() {
        return new IterateurComplexe(this);
    }
}

final class Div extends BinaryOperator {
    public Div( ArithmeticExpression operande1, ArithmeticExpression operande2 ) {
        super(operande1, operande2);
    }

    @Override
    public Object accept( Visitor v ) {
        return v.visite(this);
    }

    @Override
    public Iterator iterator() {
        return new IterateurComplexe(this);
    }
}

/**
 * Patron Visitor
 * L'implémentation nécessite ensuite de définir la hiérarchie des visiteurs.
 * Les différents visiteurs héritent de la classe abstraite Visitor.
 */
abstract class Visitor {
    public abstract Object visite( Constante n );

    public abstract Object visite( Variable n );

    public abstract Object visite( Plus a );

    public abstract Object visite( Mult m );

    public abstract Object visite( Sub m );

    public abstract Object visite( Div m );
}

/**
 * Evaluation d'expressions arithmétiques.
 */
final class Evaluation extends Visitor {
    private final double _variableValue;

    public Evaluation( double value ) {
        _variableValue = value;
    }

    public Object visite( Constante expression ) {
        return expression.getValue();
    }

    public Object visite( Variable expression ) {
        return _variableValue;
    }

    public Object visite( Plus expression ) {
        return (double) expression.getOperande1().accept(this)
                + (double) expression.getOperande2().accept(this);
    }

    public Object visite( Sub expression ) {
        return (double) expression.getOperande1().accept(this)
                - (double) expression.getOperande2().accept(this);
    }

    public Object visite( Mult expression ) {
        return (double) expression.getOperande1().accept(this)
                * (double) expression.getOperande2().accept(this);
    }

    public Object visite( Div expression ) {
        return (double) expression.getOperande1().accept(this)
                / (double) expression.getOperande2().accept(this);
    }
}

/**
 * Patron Iterateur.
 */

// ITERATEURS
class IterateurSimple implements Iterator {
    private boolean _hasNext = true;
    private final ArithmeticExpression _expression;

    public IterateurSimple( ArithmeticExpression expression ) {
        _expression = expression;
    }

    @Override
    public boolean hasNext() {
        return _hasNext;
    }

    @Override
    public ArithmeticExpression next() {
        _hasNext = false;
        return _expression;
    }
}

class IterateurComplexe implements Iterator {
    private final BinaryOperator _expression;
    private final Iterator _iterator1;
    private final Iterator _iterator2;

    public IterateurComplexe( ArithmeticExpression e ) {
        _expression = (BinaryOperator) e;
        _iterator1 = _expression.getOperande1().iterator();
        _iterator2 = _expression.getOperande2().iterator();
    }

    @Override
    public boolean hasNext() {
        return _iterator1.hasNext() || _iterator2.hasNext();
    }

    @Override
    public ArithmeticExpression next() throws NoSuchElementException {
        if (_iterator1.hasNext()) {
            return _iterator1.next();
        } else if (_iterator2.hasNext()) {
            return _iterator2.next();
        } else {
            throw new NoSuchElementException();
        }
    }
}
Modifié le: Thursday 9 November 2017, 08:00