Publié le 30/09/2010
Auteur axel
Réseaux sociaux
0 partages
0 tweets
0 plus
0 commentaires

Calculer le resultat d'une operation mathematique

A partir d'une série d'opérations mathématiques, la class EquationSolver calcule le résultat numérique. Toutes les opérations de bases sont supportées:
- addition, soustraction,
- multiplication, division.

Interpreteur mathematique

L'auteur Mark Alexander Edwards a fait évoluer l'interpréteur mathématique en y ajoutant les nombres comportant des décimales et les valeurs négatives.
import java.util.*;
import java.io.*;
import java.text.*;
import java.math.*;
 
/****************************************
 * @Author: Mark Alexander Edwards Jr.
 *
 * Utility class for solving equations.
 ****************************************/
public final class EquationSolver {    // Utility classes don't need extensions!
 
    private EquationSolver() {
    }    // Utility classes don't need to be instantiated!
 
    /*Constants*/
    private static final Character POW = new Character('^');
    private static final Character MUL = new Character('*');
    private static final Character DIV = new Character('/');
    private static final Character MOD = new Character('%');
    private static final Character ADD = new Character('+');
    private static final Character[] firstSet = {POW}, secondSet = {MUL, DIV, MOD}, thirdSet = {ADD};
    private static final DecimalFormat DF = new DecimalFormat();
    private static final StringBuffer SB = new StringBuffer();
    private static final MathContext MC = new MathContext(40);
 
    private enum Direction {
 
        L_TO_R,
        R_TO_L
    };
 
    /**
     * A Means of testing the program.
     */
    public static void main(String... args) {
        System.out.println();
        System.out.println(EquationSolver.solve("5 + 3 * (8 - 4)"));
        System.out.println();
        System.out.println(EquationSolver.solve("12 / (3 * 4) + 5"));
        System.out.println();
        InputStreamReader isr = new InputStreamReader(System.in);
        BufferedReader br = new BufferedReader(isr);
        while (true) {
            System.out.print("Enter an equation you would like to solve n(or enter EXIT to exit program): ");
            try {
                String temp = br.readLine();
 
                if (temp.equalsIgnoreCase("exit")) {
                    try {
                        isr.close();
                        br.close();
                    } catch (Exception f) {
                    } finally {
                        System.exit(0);
                    }
                }
 
                long t1 = System.nanoTime();
                System.out.println("Answer: " + EquationSolver.solve(temp, 4));
                long t2 = System.nanoTime();
                System.out.println("nTime taken to calculate value: " + (t2 - t1) + " nanoseconds");
            } catch (Exception e) {
            }
        }
    }
 
    /**
     * Performs an operation on the two numbers specified
     */
    private static String doOperation(String lhs, char operator, String rhs) {
        BigDecimal bdLhs = new BigDecimal(lhs);
        BigDecimal bdRhs = new BigDecimal(rhs);
        switch (operator) {
            case '^':
                return "" + Math.pow(bdLhs.doubleValue(), bdRhs.doubleValue());
            case '*':
                return "" + bdLhs.multiply(bdRhs).toString();
            case '/':
                return "" + bdLhs.divide(bdRhs, MC).toString();
            case '+':
                return "" + bdLhs.add(bdRhs).toString();
            case '%':
                return "" + bdLhs.remainder(bdRhs).toString();
        }
        return "";
    }
 
    /**
     * Returns a corrected version of the String, which is one that
     * has its first and last paranthesis removed.
     */
    private static String correctedString(String arg) {
 
        StringBuilder sb = new StringBuilder(); // A Mutable String
        boolean foundFirst = false;
        for (int i = 0; i < arg.length(); i++) {
            if (foundFirst == false && arg.charAt(i) == '(') {
                foundFirst = true;
            } else {
                sb.append(arg.charAt(i));
            }
        }
 
        arg = new StringBuilder(sb.reverse()).toString();
        sb.delete(0, sb.length());
 
        foundFirst = false;
        for (int i = 0; i < arg.length(); i++) {
            if (foundFirst == false && arg.charAt(i) == ')') {
                foundFirst = true;
            } else {
                sb.append(arg.charAt(i));
            }
        }
 
        return arg = new StringBuilder(sb.reverse()).toString();
    }
 
    /**
     * Provides a means of halting a process for a specified amount of time
     * without directly using the static Thread method sleep.
     *
     * Used for debugging purposes
     */
    private static void sleep(int mill) {
        long t1 = System.currentTimeMillis();
        long t2 = t1 + mill;
        while ((t1 = System.currentTimeMillis()) < t2);
    }
 
    /**
     * Returns the a String that all of the characters the parameter argu
     * has, minus the space characters in the String
     */
    private static String removeSpaces(String argu) {
        String temp = "";
 
        for (int i = 0; i < argu.length(); i++) {
            if (argu.charAt(i) != ' ') {
                temp += "" + argu.charAt(i);
            }
        }
 
        return temp;
    }
 
    /**
     * Contains an expression that exists within parenthesis
     * i.e., (5+3), (6 + 2), etc.
     *
     * If a set of paranethesis exists within the expression, it must be resolved
     * by using another expression object to solve the inner expression.
     * i.e., (5 + 3 - 2 + (8 * 7) ) would first result in an ExpressionNode consisting of
     * a call to another expression to Solve the inner expression
     *
     * Returns the result of the calculated ExpressionNode.
     * If another expression is found within this one,
     * a new ExpressionNode will be created and will solve
     * the inner expression.
     */
    private static String parse(String arg) {
 
        String expression = removeSpaces(correctedString(arg));
        String finalExpression = "";
        boolean operatorEncountered = true;
        boolean initialValue = true;
        for (int i = 0; i < expression.length(); i++) {
            if (expression.charAt(i) == '(') {
                String multiply = "";
                if (operatorEncountered == false && initialValue == false) {
                    multiply += "*";
                }
 
                String placeHolder = "(";
                int valuesCounted = 1;
                operatorEncountered = false;
                for (int j = i + 1; valuesCounted != 0; j++) {
                    if (expression.charAt(j) == '(') {
                        valuesCounted++;
                    } else if (expression.charAt(j) == ')') {
                        valuesCounted--;
                    }
                    placeHolder += "" + expression.charAt(j);
                }
 
                String evaluatedString = parse(placeHolder);
                finalExpression += multiply + evaluatedString;
                i += (placeHolder.length() - 1);
            } else {
                if (expression.charAt(i) == '-' && operatorEncountered == false) {
                    finalExpression += ((!initialValue) ? "+" : "") + expression.charAt(i);
                } else if (expression.charAt(i) == '-' && operatorEncountered == true) {
                    finalExpression += "-1*";
                } else {
                    finalExpression += expression.charAt(i);
                }
 
                if ((expression.charAt(i) == '+'
                        || expression.charAt(i) == '/'
                        || expression.charAt(i) == '^'
                        || expression.charAt(i) == '*'
                        || expression.charAt(i) == '%'
                        || expression.charAt(i) == '-')) {
                    operatorEncountered = true;
                } else if (expression.charAt(i) != ' ') {
                    operatorEncountered = false;
                }
            }
            initialValue = false;
        }
 
        finalExpression = removeSpaces(finalExpression);
        String perfectExpression = "";
 
        for (int i = 0; i < finalExpression.length(); i++) {
            if ((i + 1) < finalExpression.length()) {
                if (finalExpression.charAt(i) == '-' && finalExpression.charAt(i + 1) == '-') {
                    i += 2;
                }
            }
            perfectExpression += "" + finalExpression.charAt(i);
        }
        finalExpression = perfectExpression;
 
        ArrayList<String> totalNumbers = new ArrayList<String>(0);
        ArrayList<Character> totalOperations = new ArrayList<Character>(0);
        System.out.println(finalExpression);
 
        for (int i = 0; i < finalExpression.length(); i++) {
            if (finalExpression.charAt(i) >= '0' && finalExpression.charAt(i) <= '9'
                    || finalExpression.charAt(i) == '-' || finalExpression.charAt(i) == '.'
                    || finalExpression.charAt(i) == ',') {
                String temp = "";
                for (int j = i; j < finalExpression.length(); j++) {
                    if (finalExpression.charAt(j) >= '0' && finalExpression.charAt(j) <= '9'
                            || finalExpression.charAt(j) == '-' || finalExpression.charAt(j) == '.'
                            || finalExpression.charAt(j) == ',') {
                        temp += "" + finalExpression.charAt(j);
                    } else {
                        break;
                    }
                }
                totalNumbers.add(temp);
                i += temp.length() == 0 ? 0 : (temp.length() - 1);
            } else if (finalExpression.charAt(i) == '*'
                    || finalExpression.charAt(i) == '/'
                    || finalExpression.charAt(i) == '^'
                    || finalExpression.charAt(i) == '+'
                    || finalExpression.charAt(i) == '%') {
                totalOperations.add(new Character(finalExpression.charAt(i)));
            }
        }
 
        calculate(totalNumbers, totalOperations, firstSet, Direction.R_TO_L);
        calculate(totalNumbers, totalOperations, secondSet, Direction.L_TO_R);
        calculate(totalNumbers, totalOperations, thirdSet, Direction.L_TO_R);
 
        return totalNumbers.get(0);
    }
 
    /**
     * Returns true if the target character exists in the set of Character operands, returns false otherwise.
     */
    private static boolean containsCharacter(Character anOperation, Character operands[]) {
        for (Character item : operands) {
            if (anOperation.equals(item)) {
                return true;
            }
        }
        return false;
    }
 
    /**
     * Attempts to solve an equation that is seperated into a set of numbers and operands.
     * (More to add)
     */
    private static void calculate(ArrayList<String> totalNumbers, ArrayList<Character> totalOperations, Character operands[], Direction dir) {
        String result = "";
        if (dir == Direction.L_TO_R) {
            for (int i = 0; i < totalOperations.size(); i++) {
                if (containsCharacter(totalOperations.get(i), operands)) {
                    result = doOperation(totalNumbers.get(i), (char) totalOperations.get(i), totalNumbers.get(i + 1));
                    totalNumbers.set(i, result);
                    totalOperations.remove(i);
                    totalNumbers.remove(i + 1);
                    i--;
                }
            }
        } else if (dir == Direction.R_TO_L) {
            for (int i = totalOperations.size() - 1; i >= 0; i--) {
                if (containsCharacter(totalOperations.get(i), operands)) {
                    result = doOperation(totalNumbers.get(i), (char) totalOperations.get(i), totalNumbers.get(i + 1));
                    totalNumbers.set(i, result);
                    totalOperations.remove(i);
                    totalNumbers.remove(i + 1);
                }
            }
        }
    }
 
    /**
     * Checks to see if the expression is solvable or not.
     *
     * This method is actually a misnomer, because more restrictions
     * should be put in place on what a user can determine as solvable.
     */
    private static boolean isSolvable(String eq) {
 
        int paranthesisCount = 0;    // assuming 0 paranthesis to begin with
        for (char element : eq.toCharArray()) {    // for every char in the String eq
            if (element == '(') // if the element is a left paranthesis
            {
                paranthesisCount++;    // increment the paranthesisCount
            } else if (element == ')') // else if the element is a right paranthesis
            {
                paranthesisCount--;    // decrement the paranthesisCount
            }
            if (paranthesisCount < 0) // if brackets aren't in correct order, return false
            {
                return false;
            }
        }
        return paranthesisCount == 0;    // return true if paranthesisCount is zero, otherwise return false
    }
 
    /**
     * Attempts to solve an equation
     */
    public static String solve(String eq) {
        if (isSolvable(eq)) {
            System.out.println(eq);    // Prints out the equation before it is parsed
            String value = "(" + eq + ")";    // Appending paranthesis to the equation for accuracy
            return parse(value); //    returning the final value of the expression
        } else {
            return "";
        }
    }
 
    /**
     * Attempts to solve an equation, with the precision factor taken into account.
     *
     * The maximum precision is 40, only because the max precision for the MathContext object is 40
     * though this is not required and can be changed in future versions.
     */
    public static String solve(String eq, int precision) {
        SB.delete(0, SB.length());
        return DF.format((double) Double.parseDouble(solve(eq)), SB, new FieldPosition(precision)).toString();    // formatted answer
    }
}


Ajouter un commentaire

Les champs marqués d'un * sont obligatoires, les adresses emails se sont pas publiées.

A lire aussi

Réseaux sociaux
Présentation de l'article
Catégorie
java - class
Mise a jour
30/09/2010
Visualisation
vu 3180 fois
Public
Internaute
Auteur de la publication
Axel
Membre junior
Auteur de 51 articles
|BIO_PSEUDO|
Commentaires récents

Publié par caledonien dans php5

merci c'est parfait

Publié par roundge dans php5

Bien ! Merci pour cette petite classe en php bien pratique !
J'avais 2000 photos libres de droits à télécharger sur un site, dans un dossier ou les fichiers ne sont pas list&e...

Publié par Juslin dans java

Ca tombe bien et merci.

Publié par Do dans tuto

Et lorsque l'on a un recordset a parcourir ? Que faut-il passer a la vue ? ligne par ligne ou un tableau ? ?
Le PHP est a lui seul deja un systeme de template :
>?php
echo $titre;
?>

Publié par foufou0406 dans CMS

merci !!!