jeudi 14 janvier 2010

Google prend Sarko pour un trou du cul du web

Rien à voir avec Java, mais je trouvais l'info intéressante/marrante donc je vous la transmet ;) (surtout que ça fait déjà depuis juillet que ça existe et qu'on en parle jamais !)

Le lien : Google prend Sarko pour un trou de cul du web

lundi 4 janvier 2010

Eval en java - Evaluer des calculs

En javascript, il existe une méthode eval(String); qui permet d'évaluer un string comme étant le nom d'une méthode, un calcul ou autre chose.

Par exemple :
alert(eval("3+4")); affiche la boite d'alerte contenant 7

Mais en java, ce n'est pas aussi simple, pour évaluer un calcul entré par l'utilisateur par exemple, il faut crée soit même une méthode qui analyse le string et qui en calcul le résultat !

Voici quelques pistes pour vous aider à faire une méthode de ce genre. Il existe plusieurs façon de le faire mais en voici une (je ne sais pas si c'est la meilleur) :

Créer une méthode (appelé eval par exemple) :
public double eval(String s){
//Contenu ici
}


Ensuite, une première partie de cette méthode prendra le contenu de la parenthèse et la remplacera par son chiffre. Pour isoler les parenthèses vous pouvez utiliser un split ou un substring avec un indexOf
Imaginons que vous avez isoler votre paranthèse de facon à ce que txtAvt contienne ce qu'il y a avant la parenthèse, txtApres ce qu'il y a après et parenthese le contenu de la parenthese.

Vous pouvez alors faire :
return eval(txtAvt+eval(parenthese).toString()+txtApres)

Ensuite (s'il n'y a pas de parenthèse la méthode continue a s'exécuter jusqu'à arriver sur un autre return) il faut couper le string (avec un split) selon les sommes et les différences :
En effet, si on a le calcul 3/2+5*3 il faut d'abord faire 3/2 | (5*3)
Si vous avez un String[] somme qui contient par exemple toutes les sommes faites une boucle qui ajoute eval(somme[i]); à une variable (result par exemple) et retournez la variable (result) à la fin de la boucle :

double result = 0;
for(int i=0;i‹somme.length;i++){
result +=somme[i];
}
return result;

Même procédé pour la multiplication et la division

Et la fin de votre méthode ne sera exécutée que s'il n'y a plus de + - * / et () dans votre string donc vous pouvez faire un Double.parseDouble(s); si s représente le string à convertir. N'oubliez pas de faire un try{ ... } catch(NumberFormatException e){ ... } de manière a prévenir des erreurs.

Note supplémentaire
Attention, le split avec le fois (*) et le plus + ne fonctionne pas correctement car le split prend en compte les expressions régulières. Une solution simple est de faire
s.replace('+','P').split("P");
au lieu de
s.split("+");
(mais il ne faut pas que s contiennent d'autres caractères 'P' !)

et s.replace('*','x').split("x");
au lieu de
s.split("x");

Vous pouvez aussi faire un s.replace(',','.'); pour que les virgules soient correctement interprétés par Double.parseDouble(s) ! (sinon 3,2345 renvoi une erreur car il faut écrire 3.2345)