ayuda a mejorar un codigo de java
son dos clases una es la cabesera del aplet y la otra el codigo se ejecuta como aplet lo que nesesito es que me mande mensajes de error al tratar de evaluar logaritmos negativos que no existen y senos y cosenos que no existen
//*ELAVORADO POR //*
//Clases importadas
import java.util.*;
public class Parseador{
//VARIABLES PRIVADAS
//Guarda la 煤ltima expresi贸n que se tradujo a postfijo para poder evaluar en ella sin dar una nueva expresi贸n
private String ultimaParseada;
//CONSTRUCTORES
public Parseador(){
ultimaParseada="0";
}
//FUNCIONES PUBLICAS
/**
*La funci贸n que parsea la expresi贸n a notaci贸n postfija.
*@param expresion El string con la expresi贸n a parsear.
*@return Un String con la expresi贸n parseada en notaci贸n postfija.
*@exception SintaxException Error de escritura en la expresi贸n.
*/
public String parsear(String expresion) throws SintaxException{
Stack PilaNumeros=new Stack(); //Pila donde se guardar谩n los n煤meros al parsear
Stack PilaOperadores= new Stack(); //Pila donde se guardar谩n los operadores al parsear
String expr=quitaEspacios(expresion.toLowerCase()); //La expresi贸n sin espacios ni may煤sculas.
String fragmento; //Guarda el fragmento de texto que se est茅 utilizando en el momento (ya sea un n煤mero, un operador, una funci贸n, etc.)
int pos=0, tamano=0; //pos marca la posici贸n del caracter que se est谩 procesando actualmente en el String. tamano indica el tama帽o del texto que se procesa en ese momento.
byte cont=1; //contador indica el n煤mero de caracteres que se sacan del string en un momento indicado, este no puede ser m谩s de seis (la funci贸n con m谩s caracteres tiene seis)
//Este es un arreglo de Strings que guarda todas las funciones y expresiones permitidas, incluso n煤meros, y los acomoda en cada posici贸n de acuerdo a su tama帽o
final String funciones[]={"1 2 3 4 5 6 7 8 9 0 ( ) x e + - * / ^ %",
"pi",
"ln(",
"log( abs( sen( sin( cos( tan( sec( csc( cot( sgn(",
"rnd() asen( asin( acos( atan( asec( acsc( acot( senh( sinh( cosh( tanh( sech( csch( coth( sqrt(",
"round( asenh( acosh( atanh( asech( acsch( acoth("};
//Todas las funciones que trabajan como par茅ntesis de apertura est谩n aqu铆.
final String parentesis="( ln log abs sen sin cos tan sec csc cot sgn asen asin acos atan asec acsc acot senh sinh cosh tanh sech csch coth sqrt round asenh asinh acosh atanh asech acsch acoth";
/*
*Esta variable 'anterior' se utiliza para saber cu谩l hab铆a sido la 煤ltima
*expresi贸n parseada y verificar si hay un error en la expresi贸n o si hay
*alg煤n menos unario en la expresi贸n, se utiliza:
*0 : no ha parseado nada
*1 : un n煤mero (n煤mero, pi, e, x)
*2 : un operador binario (+ - * / ^ %)
*3 : un par茅ntesis (( sen( cos( etc.)
*4 : cierre de par茅ntesis ())
*Si no se ha parseado nada puede ser cualquier cosa menos (+ * / ^ %)
*Si el anterior fue un n煤mero puede seguir cualquier cosa
*Si lo anterior fue un operador puede seguir cualquier cosa menos otro operador (con excepci贸n de -)
*Si lo anterior fue un par茅ntesis puede seguir cualquier cosa menos (+ * / ^ %)
*Si lo anterior fue un cierre de par茅ntesis debe seguir un operador, un n煤mero (en cuyo caso hay un por oculto) u otro par茅ntesis (tambi茅n hay un por oculto)
*/
byte anterior=0;
try{
while(pos<expr.length()){ //Haga mientras la posici贸n sea menor al tama帽o del String (mientras este dentro del string)
tamano=0;
cont=1;
while (tamano==0 && cont<=6){ //Este while revisa si el pedazo del texto sacado concuerda con algo conocido
if(pos+cont<=expr.length() && funciones[cont-1].indexOf(expr.substring(pos,pos+cont))!=-1){
tamano=cont;
}
cont++;
}
if (tamano==0){ //Si no encontr贸 nada es por que hubo un error, se pone la 霉ltima parseada en cero y se lanza una excepci贸n
ultimaParseada="0";
throw new SintaxException("ERROR EN LA EXPRESI脫N FIJATE BIEN VAMOS TU PUEDES ");
}
else if(tamano==1){ //Si encontr贸 algo de tama帽o uno
if(isNum(expr.substring(pos,pos+tamano))){ //Si es un n煤mero se encarga de sacarlo completo
if(anterior==1 || anterior==4){//si hay una multiplicaci贸n oculta
sacaOperadores(PilaNumeros, PilaOperadores, "*");
}
fragmento=""; //aqu铆 se guardar谩 el n煤mero sacado
do{ //H谩galo mientras lo que siga sea un n煤mero o un punto o una coma
fragmento=fragmento+expr.charAt(pos);
pos++;
}while(pos<expr.length() && (isNum(expr.substring(pos,pos+tamano)) || expr.charAt(pos) == '.' || expr.charAt(pos) == ','));
try{ //Trate de convertirlo en un n煤mero
Double.valueOf(fragmento);
}
catch(NumberFormatException e){ //Si no pudo pasarlo a n煤mero hay un error
ultimaParseada="0";
throw new SintaxException("NUMERO MAL DIJITADO ");
}
PilaNumeros.push(new String(fragmento));
anterior=1;
pos--;
}
else if (expr.charAt(pos)=='x' || expr.charAt(pos)=='e'){ //Si es un n煤mero conocido
if(anterior==1 || anterior==4){//si hay una multiplicaci贸n oculta
sacaOperadores(PilaNumeros, PilaOperadores, "*");
}
PilaNumeros.push(expr.substring(pos,pos+tamano));
anterior=1;
}
else if (expr.charAt(pos)=='+' || expr.charAt(pos)=='*' || expr.charAt(pos)=='/' || expr.charAt(pos)=='%'){ //Si es suma, multiplicaci贸n o divisi贸n
if (anterior==0 || anterior==2 || anterior==3)//Hay error si antes de los operadores no hay nada, hay un par茅ntesis de apertura o un operador
throw new SintaxException("ERROR EN LA EXPRESI脫N");
sacaOperadores(PilaNumeros, PilaOperadores, expr.substring(pos,pos+tamano));
anterior=2;
}
else if (expr.charAt(pos)=='^'){ //Si es una potencia
if (anterior==0 || anterior==2 || anterior==3) //Hay error si antes de un apotencia no hay nada, hay un par茅ntesis de apertura o un operador
throw new SintaxException("ERROR EN LA EXPRESION SIGUE NO TE DETENGAS ");
PilaOperadores.push(new String("^"));
anterior=2;
}
else if (expr.charAt(pos)=='-'){ //Si es una resta
if(anterior==0 || anterior==2 || anterior==3){//si hay un menos unario
PilaNumeros.push(new String("-1"));
sacaOperadores(PilaNumeros, PilaOperadores, "*");
}
else{//si el menos es binario
sacaOperadores(PilaNumeros, PilaOperadores, "-");
}
anterior=2;
}
else if (expr.charAt(pos)=='('){
if (anterior==1 || anterior == 4){ //si hay una multiplicaci贸n oculta
sacaOperadores(PilaNumeros, PilaOperadores, "*");
}
PilaOperadores.push(new String("("));
anterior=3;
}
else if (expr.charAt(pos)==')'){
if(anterior!=1 && anterior !=4) //Antes de un cierre de par茅ntesis s贸lo puede haber un n煤mero u otro cierre de par茅ntesis, sino hay un error
throw new SintaxException("ERROREN LA EXPRESI脫N VAMOS");
while(!PilaOperadores.empty() && parentesis.indexOf(((String)PilaOperadores.peek()))==-1){
sacaOperador(PilaNumeros, PilaOperadores);
}
if(!((String)PilaOperadores.peek()).equals("(")){
PilaNumeros.push(new String(((String)PilaNumeros.pop()) + " " + ((String)PilaOperadores.pop())));
}
else{
PilaOperadores.pop();
}
anterior=4;
}
}
else if(tamano>=2){ //Si lo encontrado es de tama帽o dos o mayor (todas las funciones se manejan igual)
fragmento=expr.substring(pos,pos+tamano);
if(fragmento.equals("pi")){ //Si es el n煤mero pi
if(anterior==1 || anterior==4){//si hay una multiplicaci贸n oculta
sacaOperadores(PilaNumeros, PilaOperadores, "*");
}
PilaNumeros.push(fragmento);
anterior=1;
}
else if(fragmento.equals("rnd()")){ //Si es la funci贸n que devuelve un n煤mero aleatorio (la 煤nica funci贸n que se maneja como un n煤mero)
if(anterior==1 || anterior==4){//si hay una multiplicaci贸n oculta
sacaOperadores(PilaNumeros, PilaOperadores, "*");
}
PilaNumeros.push("rnd");
anterior=1;
}
else{ //Si es cualquier otra funci贸n
if (anterior==1 || anterior == 4){ //si hay una multiplicaci贸n oculta
sacaOperadores(PilaNumeros, PilaOperadores, "*");
}
PilaOperadores.push(fragmento.substring(0,fragmento.length()-1)); //Se guarda en la pila de funciones sin el par茅ntesis de apertura (en postfijo no se necesita)
anterior=3;
}
}
pos+=tamano;
}
//Procesa al final
while(!PilaOperadores.empty()){ //Saca todos los operadores mientras la pila no est茅 vac铆a
if(parentesis.indexOf((String)PilaOperadores.peek())!=-1)
throw new SintaxException("HAY UN PARENTESIS DE MAS");
sacaOperador(PilaNumeros, PilaOperadores);
}
}
catch(EmptyStackException e){ //Si en alg煤n momento se intenta sacar de la pila y est谩 vac铆a hay un error
ultimaParseada="0";
throw new SintaxException("EXPRESI脫N MAL DIGITADA");
}
ultimaParseada=((String)PilaNumeros.pop()); //Se obtiene el resultado final
if(!PilaNumeros.empty()){ //Si la pila de n煤meros no qued贸 vac铆a hay un error
ultimaParseada="0";
throw new SintaxException("ERROR EN LA EXPRESI脫N");
}
return ultimaParseada; //Se devuelve el resultado evaluado
}//Parsear
/**
*Esta es la funci贸n que eval煤a una expresi贸n parseada en un valor double.
*@param expresionParseada Esta es una expresi贸n en notaci贸n postfija (se puede obtener con la funci贸n parsear).
*@param x El valor double en el que se evaluar谩 la funci贸n.
*@return El resultado (un valor double) de evaluar x en la expresi贸n.
*@exception ArithmeticException Error al evaluar en los reales.
*/
public double f(String expresionParseada, double x) throws ArithmeticException{
Stack pilaEvaluar = new Stack(); //Pila de doubles para evaluar
double a, b; //Estos valores son los que se van sacando de la pila de doubles
StringTokenizer tokens=new StringTokenizer(expresionParseada); //La expresi贸n partida en tokens
String tokenActual; //El token que se procesa actualmente
try{
while(tokens.hasMoreTokens()){ //Haga mientras hayan m谩s tokens
tokenActual=tokens.nextToken();
/*
*La idea aqu铆 es sacar el token que sigue y verificar qu茅 es ese
*token y manejarlo de manera:
*Si es un n煤mero se introduce en la pila de n煤meros
*Si es una funci贸n se sacan el valor o los valores necesarios de la pila
*de n煤meros y se mete el valor evaluado en la funci贸n correspondiente (u operador correspondiente).
*/
if(tokenActual.equals("e")){ //Si es el n煤mero e
pilaEvaluar.push(new Double(Math.E));
}
else if(tokenActual.equals("pi")){//Si es el n煤mero pi
pilaEvaluar.push(new Double(Math.PI));
}
else if(tokenActual.equals("x")){//Si es una x se introduce el valor a evaluar por el usuario
pilaEvaluar.push(new Double(x));
}
else if(tokenActual.equals("+")){//Si es una suma se sacan dos n煤meros y se suman
b=((Double)pilaEvaluar.pop()).doubleValue();
a=((Double)pilaEvaluar.pop()).doubleValue();
pilaEvaluar.push(new Double(a+b));
}
else if(tokenActual.equals("-")){//Si es resta se sacan dos valores y se restan (as铆 con todos los operadores)
b=((Double)pilaEvaluar.pop()).doubleValue();
a=((Double)pilaEvaluar.pop()).doubleValue();
pilaEvaluar.push(new Double(a-b));
}
else if(tokenActual.equals("*")){//Multiplicaci贸n
b=((Double)pilaEvaluar.pop()).doubleValue();
a=((Double)pilaEvaluar.pop()).doubleValue();
pilaEvaluar.push(new Double(a*b));
}
else if(tokenActual.equals("/")){//Divisi贸n
b=((Double)pilaEvaluar.pop()).doubleValue();
a=((Double)pilaEvaluar.pop()).doubleValue();
pilaEvaluar.push(new Double(a/b));
}
else if(tokenActual.equals("^")){//Potencia
b=((Double)pilaEvaluar.pop()).doubleValue();
a=((Double)pilaEvaluar.pop()).doubleValue();
pilaEvaluar.push(new Double(Math.pow(a,b)));
}
else if(tokenActual.equals("%")){//Resto de la divisi贸n entera
b=((Double)pilaEvaluar.pop()).doubleValue();
a=((Double)pilaEvaluar.pop()).doubleValue();
pilaEvaluar.push(new Double(a%b));
}
else if(tokenActual.equals("ln")){//Si es logaritmo natural s贸lo se saca un valor de la pila y se eval煤a
a=((Double)pilaEvaluar.pop()).doubleValue();
pilaEvaluar.push(new Double(Math.log(a)));
}
else if(tokenActual.equals("log")){//Logaritmo en base 10
a=((Double)pilaEvaluar.pop()).doubleValue();
pilaEvaluar.push(new Double(Math.log(a)/Math.log(10)));
}
else if(tokenActual.equals("abs")){//Valor absoluto
a=((Double)pilaEvaluar.pop()).doubleValue();
pilaEvaluar.push(new Double(Math.abs(a)));
}
else if(tokenActual.equals("rnd")){//Un n煤mero a random simplemente se mete en la pila de n煤meros
pilaEvaluar.push(new Double(Math.random()));
}
else if(tokenActual.equals("sen") || tokenActual.equals("sin")){ //Seno
a=((Double)pilaEvaluar.pop()).doubleValue();
pilaEvaluar.push(new Double(Math.sin(a)));
}
else if(tokenActual.equals("cos")){//Coseno
a=((Double)pilaEvaluar.pop()).doubleValue();
pilaEvaluar.push(new Double(Math.cos(a)));
}
else if(tokenActual.equals("tan")){//Tangente
a=((Double)pilaEvaluar.pop()).doubleValue();
pilaEvaluar.push(new Double(Math.tan(a)));
}
else if(tokenActual.equals("sec")){//Secante
a=((Double)pilaEvaluar.pop()).doubleValue();
pilaEvaluar.push(new Double(1/Math.cos(a)));
}
else if(tokenActual.equals("csc")){//Cosecante
a=((Double)pilaEvaluar.pop()).doubleValue();
pilaEvaluar.push(new Double(1/Math.sin(a)));
}
else if(tokenActual.equals("cot")){//Cotangente
a=((Double)pilaEvaluar.pop()).doubleValue();
pilaEvaluar.push(new Double(1/Math.tan(a)));
}
else if(tokenActual.equals("sgn")){//Signo
a=((Double)pilaEvaluar.pop()).doubleValue();
pilaEvaluar.push(new Double(sgn(a)));
}
else if(tokenActual.equals("asen") || tokenActual.equals("asin")){ //Arcoseno
a=((Double)pilaEvaluar.pop()).doubleValue();
pilaEvaluar.push(new Double(Math.asin(a)));
}
else if(tokenActual.equals("acos")){//Arcocoseno
a=((Double)pilaEvaluar.pop()).doubleValue();
pilaEvaluar.push(new Double(Math.acos(a)));
}
else if(tokenActual.equals("atan")){//Arcotangente
a=((Double)pilaEvaluar.pop()).doubleValue();
pilaEvaluar.push(new Double(Math.atan(a)));
}
else if(tokenActual.equals("asec")){//Arcosecante
a=((Double)pilaEvaluar.pop()).doubleValue();
pilaEvaluar.push(new Double(Math.acos(1/a)));
}
else if(tokenActual.equals("acsc")){//Arcocosecante
a=((Double)pilaEvaluar.pop()).doubleValue();
pilaEvaluar.push(new Double(Math.asin(1/a)));
}
else if(tokenActual.equals("acot")){//Arcocotangente
a=((Double)pilaEvaluar.pop()).doubleValue();
pilaEvaluar.push(new Double(Math.atan(1/a)));
}
else if(tokenActual.equals("senh") || tokenActual.equals("sinh")){//Seno hiperb贸lico
a=((Double)pilaEvaluar.pop()).doubleValue();
pilaEvaluar.push(new Double((Math.exp(a)-Math.exp(-a))/2));
}
else if(tokenActual.equals("cosh")){//Coseno hiperb贸lico
a=((Double)pilaEvaluar.pop()).doubleValue();
pilaEvaluar.push(new Double((Math.exp(a)+Math.exp(-a))/2));
}
else if(tokenActual.equals("tanh")){//tangente hiperb贸lica
a=((Double)pilaEvaluar.pop()).doubleValue();
pilaEvaluar.push(new Double((Math.exp(a)-Math.exp(-a))/(Math.exp(a)+Math.exp(-a))));
}
else if(tokenActual.equals("sech")){//Secante hiperb贸lica
a=((Double)pilaEvaluar.pop()).doubleValue();
pilaEvaluar.push(new Double(2/(Math.exp(a)+Math.exp(-a))));
}
else if(tokenActual.equals("csch")){//Cosecante hiperb贸lica
a=((Double)pilaEvaluar.pop()).doubleValue();
pilaEvaluar.push(new Double(2/(Math.exp(a)-Math.exp(-a))));
}
else if(tokenActual.equals("coth")){//Cotangente hiperb贸lica
a=((Double)pilaEvaluar.pop()).doubleValue();
pilaEvaluar.push(new Double((Math.exp(a)+Math.exp(-a))/(Math.exp(a)-Math.exp(-a))));
}
else if(tokenActual.equals("asenh") || tokenActual.equals("asinh")){ //Arcoseno hiperb贸lico
a=((Double)pilaEvaluar.pop()).doubleValue();
pilaEvaluar.push(new Double(Math.log(a+Math.sqrt(a*a+1))));
}
else if(tokenActual.equals("acosh")){//Arcocoseno hiperb贸lico
a=((Double)pilaEvaluar.pop()).doubleValue();
pilaEvaluar.push(new Double(Math.log(a+Math.sqrt(a*a-1))));
}
else if(tokenActual.equals("atanh")){//Arcotangente hiperb贸lica
a=((Double)pilaEvaluar.pop()).doubleValue();
pilaEvaluar.push(new Double(Math.log((1+a)/(1-a))/2));
}
else if(tokenActual.equals("asech")){//Arcosecante hiperb贸lica
a=((Double)pilaEvaluar.pop()).doubleValue();
pilaEvaluar.push(new Double(Math.log((Math.sqrt(1-a*a)+1)/a)));
}
else if(tokenActual.equals("acsch")){//Arcocosecante hiperb贸lica
a=((Double)pilaEvaluar.pop()).doubleValue();
pilaEvaluar.push(new Double(Math.log((sgn(a)*Math.sqrt(a*a +1)+1)/a)));
}
else if(tokenActual.equals("acoth")){//Arcocotangente hiperb贸lica
a=((Double)pilaEvaluar.pop()).doubleValue();
pilaEvaluar.push(new Double(Math.log((a+1)/(a-1))/2));
}
else if(tokenActual.equals("sqrt")){//Ra铆z cuadrada
a=((Double)pilaEvaluar.pop()).doubleValue();
pilaEvaluar.push(new Double(Math.sqrt(a)));
}
else if(tokenActual.equals("round")){//Redondear
a=((Double)pilaEvaluar.pop()).doubleValue();
pilaEvaluar.push(new Double(Long.toString(Math.round(a))));
}
else{//si es otra cosa tiene que ser un n煤mero, simplemente se mete en la pila
pilaEvaluar.push(Double.valueOf(tokenActual));
}
}//while
}
catch(EmptyStackException e){ //Si en alg煤n momento se acab贸 la pila hay un error
throw new ArithmeticException("EXPRESI脫N MAL PARSEADA");
}
catch(NumberFormatException e){ //Si hubo error al traducir un n煤mero hay un error
throw new ArithmeticException("EXPRESI脫N MAL DIJITADA");
}
catch(ArithmeticException e){ //Cualquier otro error de divisi贸n por cero o logaritmo negativo, etc.
throw new ArithmeticException("VALOR NO REAL EN LA EXPRESI脫N ");
}
a=((Double)pilaEvaluar.pop()).doubleValue(); //El valor a devolver
if(!pilaEvaluar.empty()) //Si todav铆a qued贸 otro valor en la pila hay un error
throw new ArithmeticException("EXPRESI脫N MAL DIJITADA");
return a;
}//funcion f
/**
*Esta funci贸n evalua la 煤ltima expresi贸n parseada en el valor x.
*@param x valor a evaluar.
*@return la evaluaci贸n del polinomio en el valor x.
*/
public double f(double x) throws ArithmeticException{
try{
return f(ultimaParseada,x);
}
catch(ArithmeticException e){
throw e;
}
}//Fin de la funcion f
//FUNCIONES PRIVADAS
/*
*saca Operador es una funci贸n que se encarga de sacar un operador de la pila
*y manejarlo de manera apropiada, ya sea un operador unario o binario
*/
private void sacaOperador(Stack Numeros, Stack operadores) throws EmptyStackException{
String operador, a, b;
final String operadoresBinarios="+ - * / ^ %"; //Lista de los operadores binarios
try{
operador=(String)operadores.pop(); //Saca el operador que se debe evaluar
if(operadoresBinarios.indexOf(operador)!=-1){ //Si es un operador binario saca dos elementos de la pila y guarda la operaci贸n
b=(String)Numeros.pop();
a=(String)Numeros.pop();
Numeros.push(new String(a+" "+b+" "+operador));
}
else{ //Sino s贸lo saca un elemento
a=(String)Numeros.pop();
Numeros.push(new String(a+" "+operador));
}
}
catch(EmptyStackException e){
throw e;
}
}//saca Operador
/*
*saca Operadores saca los operadores que tienen mayor prioridad y mete el nuevo operador
*/
private void sacaOperadores(Stack PilaNumeros, Stack PilaOperadores, String operador){
//Todas las funciones que se manejan como par茅ntesis de apertura
final String parentesis="( ln log abs sen sin cos tan sec csc cot sgn asen asin acos atan asec acsc acot senh sinh cosh tanh sech csch coth sqrt round asenh asinh acosh atanh asech acsch acoth";
//mientras la pila no est茅 vac铆a, el operador que sigue no sea un par茅ntesis de apertura, la longitud del operador sea uno (para que sea un operador), y la prioridad indique que tiene que seguir sacando elementos
while(!PilaOperadores.empty() && parentesis.indexOf((String)PilaOperadores.peek())==-1 && ((String)PilaOperadores.peek()).length()==1 && prioridad(((String)PilaOperadores.peek()).charAt(0))>=prioridad(operador.charAt(0))){
sacaOperador(PilaNumeros, PilaOperadores); //Saca el siguiente operador
}
PilaOperadores.push(operador);//Al final mete el nuevo operador luego de sacar todo lo que ten铆a que sacar.
}
/*
*Funci贸n que devuelve la prioridad de una operacion
*/
private int prioridad(char s) {
if (s=='+' || s=='-') //Si es una suma o una resta devuelve cero
return 0;
else if (s=='*' || s=='/' || s=='%') //Si es multiplicaci贸n, divisi贸n o resto de divisi贸n devuelve uno
return 1;
else if (s=='^')//Si es potencia devuelve dos
return 2;
return -1; //Si no fue nada de lo anterior devuelve -1
} //Fin de la funcion prioridad
/*
*Funci贸n que pregunta si un caracter es un n煤mero o no
*/
private boolean isNum(String s) {
if (s.compareTo("0")>=0 && s.compareTo("9")<=0) //Si el caracter est谩 entre 0 y 9 (si es un n煤mero)
return true;
else
return false;
} //Fin de la funcion isNum
/*
*Quita los espacios del String con el polinomio
*/
private String quitaEspacios(String polinomio){
String unspacedString = ""; //Variable donde lee la funci贸n
for(int i = 0; i < polinomio.length(); i++){ //Le quita los espacios a la espresi贸n que ley贸
if(polinomio.charAt(i) != ' ') //Si el caracter no es un espacio lo pone, sino lo quita.
unspacedString += polinomio.charAt(i);
}//for
return unspacedString;
}//quitaEspacios
/*
*Devuelve el signo del n煤mero dado
*/
private double sgn(double a){
if(a<0) //Si el n煤mero es negativo devuelve -1
return -1;
else if(a>0)//Si es positivo devuelve 1
return 1;
else//Si no es negativo ni positivo devuelve cero
return 0;
}
//CLASES PRIVADAS
//Clase SintaxException
//Esta es la excepci贸n que se lanza si hay alg煤n error sint谩ctico en la expresi贸n
private class SintaxException extends ArithmeticException{ //En realidad extiende la ArithmeticException
public SintaxException(){ //Si se llama con el mensaje por defecto
super("ERROR EN LA SINTAXIS HAZLO BIEN DEL POLINOMIO SIGUE INTENTANDO "); //El constructor llama a la clase superior
}
public SintaxException(String e){ //si se llama con otro mensaje
super(e); //El constructor llama a la clase superior
}
}
}//fin de Parseador
import java.applet.*;
import java.awt.*;
public class PruebaParseador extends java.applet.Applet {
Parseador miparser=new Parseador(); //Constructor del parseador
String expresion=new String(); //Expresi贸n a parsear
double valor=0; //Valor en el que se va a evaluar
TextField inputexpresion = new TextField("x + 5"); //Textfield donde se digita la expresi贸n a parsear
TextField inputvalor = new TextField("0",5); //Textfield donde se digita el valor a evaluar en la expresi贸n
Button boton= new Button("EVALUAR LA EXPRECION MATEMATICA"); //Bot贸n para evaluar
TextField outputparseo = new TextField(" "); //Resultado de parsear la expresi贸n
TextField outputevaluar = new TextField(" "); //Resultado de la evaluaci贸n en la expresi贸n
Label info = new Label(" U N I V E R S I D A D I C E L C O M P I L A D O R P U T O C A R L O S ", Label.CENTER); //Label donde se dan los errores
public void init(){ //Todo se pone en el applet
add(inputexpresion);
add(inputvalor);
add(boton);
add(outputparseo);
add(outputevaluar);
add(info);
}//init
public boolean action(Event evt, Object arg){
if (evt.target instanceof Button){ //Si se apret贸 el bot贸n
try{
info.setText(""); //Se pone el Label de los errores vac铆o
expresion=inputexpresion.getText(); //Se lee la expresi贸n
valor=Double.valueOf(inputvalor.getText()).doubleValue(); //Se lee el valor a evaluar
outputparseo.setText(miparser.parsear(expresion)); //Se parsea la expresi贸n
outputevaluar.setText(""+redondeo(miparser.f(valor),5)); //Se eval煤a el valor y se redondea
}
catch(Exception e){ //Si hubo error lo pone en el Label correspondiente
info.setText(e.toString());
}
}//if del bot贸n
return true;
}//action
/*
*Se redondea un n煤mero con los decimales dados
*/
private double redondeo(double numero, int decimales){
return ((double)Math.round(numero*Math.pow(10,decimales)))/Math.pow(10,decimales);
}
}//PolCero
//*ELAVORADO POR //*
//Clases importadas
import java.util.*;
public class Parseador{
//VARIABLES PRIVADAS
//Guarda la 煤ltima expresi贸n que se tradujo a postfijo para poder evaluar en ella sin dar una nueva expresi贸n
private String ultimaParseada;
//CONSTRUCTORES
public Parseador(){
ultimaParseada="0";
}
//FUNCIONES PUBLICAS
/**
*La funci贸n que parsea la expresi贸n a notaci贸n postfija.
*@param expresion El string con la expresi贸n a parsear.
*@return Un String con la expresi贸n parseada en notaci贸n postfija.
*@exception SintaxException Error de escritura en la expresi贸n.
*/
public String parsear(String expresion) throws SintaxException{
Stack PilaNumeros=new Stack(); //Pila donde se guardar谩n los n煤meros al parsear
Stack PilaOperadores= new Stack(); //Pila donde se guardar谩n los operadores al parsear
String expr=quitaEspacios(expresion.toLowerCase()); //La expresi贸n sin espacios ni may煤sculas.
String fragmento; //Guarda el fragmento de texto que se est茅 utilizando en el momento (ya sea un n煤mero, un operador, una funci贸n, etc.)
int pos=0, tamano=0; //pos marca la posici贸n del caracter que se est谩 procesando actualmente en el String. tamano indica el tama帽o del texto que se procesa en ese momento.
byte cont=1; //contador indica el n煤mero de caracteres que se sacan del string en un momento indicado, este no puede ser m谩s de seis (la funci贸n con m谩s caracteres tiene seis)
//Este es un arreglo de Strings que guarda todas las funciones y expresiones permitidas, incluso n煤meros, y los acomoda en cada posici贸n de acuerdo a su tama帽o
final String funciones[]={"1 2 3 4 5 6 7 8 9 0 ( ) x e + - * / ^ %",
"pi",
"ln(",
"log( abs( sen( sin( cos( tan( sec( csc( cot( sgn(",
"rnd() asen( asin( acos( atan( asec( acsc( acot( senh( sinh( cosh( tanh( sech( csch( coth( sqrt(",
"round( asenh( acosh( atanh( asech( acsch( acoth("};
//Todas las funciones que trabajan como par茅ntesis de apertura est谩n aqu铆.
final String parentesis="( ln log abs sen sin cos tan sec csc cot sgn asen asin acos atan asec acsc acot senh sinh cosh tanh sech csch coth sqrt round asenh asinh acosh atanh asech acsch acoth";
/*
*Esta variable 'anterior' se utiliza para saber cu谩l hab铆a sido la 煤ltima
*expresi贸n parseada y verificar si hay un error en la expresi贸n o si hay
*alg煤n menos unario en la expresi贸n, se utiliza:
*0 : no ha parseado nada
*1 : un n煤mero (n煤mero, pi, e, x)
*2 : un operador binario (+ - * / ^ %)
*3 : un par茅ntesis (( sen( cos( etc.)
*4 : cierre de par茅ntesis ())
*Si no se ha parseado nada puede ser cualquier cosa menos (+ * / ^ %)
*Si el anterior fue un n煤mero puede seguir cualquier cosa
*Si lo anterior fue un operador puede seguir cualquier cosa menos otro operador (con excepci贸n de -)
*Si lo anterior fue un par茅ntesis puede seguir cualquier cosa menos (+ * / ^ %)
*Si lo anterior fue un cierre de par茅ntesis debe seguir un operador, un n煤mero (en cuyo caso hay un por oculto) u otro par茅ntesis (tambi茅n hay un por oculto)
*/
byte anterior=0;
try{
while(pos<expr.length()){ //Haga mientras la posici贸n sea menor al tama帽o del String (mientras este dentro del string)
tamano=0;
cont=1;
while (tamano==0 && cont<=6){ //Este while revisa si el pedazo del texto sacado concuerda con algo conocido
if(pos+cont<=expr.length() && funciones[cont-1].indexOf(expr.substring(pos,pos+cont))!=-1){
tamano=cont;
}
cont++;
}
if (tamano==0){ //Si no encontr贸 nada es por que hubo un error, se pone la 霉ltima parseada en cero y se lanza una excepci贸n
ultimaParseada="0";
throw new SintaxException("ERROR EN LA EXPRESI脫N FIJATE BIEN VAMOS TU PUEDES ");
}
else if(tamano==1){ //Si encontr贸 algo de tama帽o uno
if(isNum(expr.substring(pos,pos+tamano))){ //Si es un n煤mero se encarga de sacarlo completo
if(anterior==1 || anterior==4){//si hay una multiplicaci贸n oculta
sacaOperadores(PilaNumeros, PilaOperadores, "*");
}
fragmento=""; //aqu铆 se guardar谩 el n煤mero sacado
do{ //H谩galo mientras lo que siga sea un n煤mero o un punto o una coma
fragmento=fragmento+expr.charAt(pos);
pos++;
}while(pos<expr.length() && (isNum(expr.substring(pos,pos+tamano)) || expr.charAt(pos) == '.' || expr.charAt(pos) == ','));
try{ //Trate de convertirlo en un n煤mero
Double.valueOf(fragmento);
}
catch(NumberFormatException e){ //Si no pudo pasarlo a n煤mero hay un error
ultimaParseada="0";
throw new SintaxException("NUMERO MAL DIJITADO ");
}
PilaNumeros.push(new String(fragmento));
anterior=1;
pos--;
}
else if (expr.charAt(pos)=='x' || expr.charAt(pos)=='e'){ //Si es un n煤mero conocido
if(anterior==1 || anterior==4){//si hay una multiplicaci贸n oculta
sacaOperadores(PilaNumeros, PilaOperadores, "*");
}
PilaNumeros.push(expr.substring(pos,pos+tamano));
anterior=1;
}
else if (expr.charAt(pos)=='+' || expr.charAt(pos)=='*' || expr.charAt(pos)=='/' || expr.charAt(pos)=='%'){ //Si es suma, multiplicaci贸n o divisi贸n
if (anterior==0 || anterior==2 || anterior==3)//Hay error si antes de los operadores no hay nada, hay un par茅ntesis de apertura o un operador
throw new SintaxException("ERROR EN LA EXPRESI脫N");
sacaOperadores(PilaNumeros, PilaOperadores, expr.substring(pos,pos+tamano));
anterior=2;
}
else if (expr.charAt(pos)=='^'){ //Si es una potencia
if (anterior==0 || anterior==2 || anterior==3) //Hay error si antes de un apotencia no hay nada, hay un par茅ntesis de apertura o un operador
throw new SintaxException("ERROR EN LA EXPRESION SIGUE NO TE DETENGAS ");
PilaOperadores.push(new String("^"));
anterior=2;
}
else if (expr.charAt(pos)=='-'){ //Si es una resta
if(anterior==0 || anterior==2 || anterior==3){//si hay un menos unario
PilaNumeros.push(new String("-1"));
sacaOperadores(PilaNumeros, PilaOperadores, "*");
}
else{//si el menos es binario
sacaOperadores(PilaNumeros, PilaOperadores, "-");
}
anterior=2;
}
else if (expr.charAt(pos)=='('){
if (anterior==1 || anterior == 4){ //si hay una multiplicaci贸n oculta
sacaOperadores(PilaNumeros, PilaOperadores, "*");
}
PilaOperadores.push(new String("("));
anterior=3;
}
else if (expr.charAt(pos)==')'){
if(anterior!=1 && anterior !=4) //Antes de un cierre de par茅ntesis s贸lo puede haber un n煤mero u otro cierre de par茅ntesis, sino hay un error
throw new SintaxException("ERROREN LA EXPRESI脫N VAMOS");
while(!PilaOperadores.empty() && parentesis.indexOf(((String)PilaOperadores.peek()))==-1){
sacaOperador(PilaNumeros, PilaOperadores);
}
if(!((String)PilaOperadores.peek()).equals("(")){
PilaNumeros.push(new String(((String)PilaNumeros.pop()) + " " + ((String)PilaOperadores.pop())));
}
else{
PilaOperadores.pop();
}
anterior=4;
}
}
else if(tamano>=2){ //Si lo encontrado es de tama帽o dos o mayor (todas las funciones se manejan igual)
fragmento=expr.substring(pos,pos+tamano);
if(fragmento.equals("pi")){ //Si es el n煤mero pi
if(anterior==1 || anterior==4){//si hay una multiplicaci贸n oculta
sacaOperadores(PilaNumeros, PilaOperadores, "*");
}
PilaNumeros.push(fragmento);
anterior=1;
}
else if(fragmento.equals("rnd()")){ //Si es la funci贸n que devuelve un n煤mero aleatorio (la 煤nica funci贸n que se maneja como un n煤mero)
if(anterior==1 || anterior==4){//si hay una multiplicaci贸n oculta
sacaOperadores(PilaNumeros, PilaOperadores, "*");
}
PilaNumeros.push("rnd");
anterior=1;
}
else{ //Si es cualquier otra funci贸n
if (anterior==1 || anterior == 4){ //si hay una multiplicaci贸n oculta
sacaOperadores(PilaNumeros, PilaOperadores, "*");
}
PilaOperadores.push(fragmento.substring(0,fragmento.length()-1)); //Se guarda en la pila de funciones sin el par茅ntesis de apertura (en postfijo no se necesita)
anterior=3;
}
}
pos+=tamano;
}
//Procesa al final
while(!PilaOperadores.empty()){ //Saca todos los operadores mientras la pila no est茅 vac铆a
if(parentesis.indexOf((String)PilaOperadores.peek())!=-1)
throw new SintaxException("HAY UN PARENTESIS DE MAS");
sacaOperador(PilaNumeros, PilaOperadores);
}
}
catch(EmptyStackException e){ //Si en alg煤n momento se intenta sacar de la pila y est谩 vac铆a hay un error
ultimaParseada="0";
throw new SintaxException("EXPRESI脫N MAL DIGITADA");
}
ultimaParseada=((String)PilaNumeros.pop()); //Se obtiene el resultado final
if(!PilaNumeros.empty()){ //Si la pila de n煤meros no qued贸 vac铆a hay un error
ultimaParseada="0";
throw new SintaxException("ERROR EN LA EXPRESI脫N");
}
return ultimaParseada; //Se devuelve el resultado evaluado
}//Parsear
/**
*Esta es la funci贸n que eval煤a una expresi贸n parseada en un valor double.
*@param expresionParseada Esta es una expresi贸n en notaci贸n postfija (se puede obtener con la funci贸n parsear).
*@param x El valor double en el que se evaluar谩 la funci贸n.
*@return El resultado (un valor double) de evaluar x en la expresi贸n.
*@exception ArithmeticException Error al evaluar en los reales.
*/
public double f(String expresionParseada, double x) throws ArithmeticException{
Stack pilaEvaluar = new Stack(); //Pila de doubles para evaluar
double a, b; //Estos valores son los que se van sacando de la pila de doubles
StringTokenizer tokens=new StringTokenizer(expresionParseada); //La expresi贸n partida en tokens
String tokenActual; //El token que se procesa actualmente
try{
while(tokens.hasMoreTokens()){ //Haga mientras hayan m谩s tokens
tokenActual=tokens.nextToken();
/*
*La idea aqu铆 es sacar el token que sigue y verificar qu茅 es ese
*token y manejarlo de manera:
*Si es un n煤mero se introduce en la pila de n煤meros
*Si es una funci贸n se sacan el valor o los valores necesarios de la pila
*de n煤meros y se mete el valor evaluado en la funci贸n correspondiente (u operador correspondiente).
*/
if(tokenActual.equals("e")){ //Si es el n煤mero e
pilaEvaluar.push(new Double(Math.E));
}
else if(tokenActual.equals("pi")){//Si es el n煤mero pi
pilaEvaluar.push(new Double(Math.PI));
}
else if(tokenActual.equals("x")){//Si es una x se introduce el valor a evaluar por el usuario
pilaEvaluar.push(new Double(x));
}
else if(tokenActual.equals("+")){//Si es una suma se sacan dos n煤meros y se suman
b=((Double)pilaEvaluar.pop()).doubleValue();
a=((Double)pilaEvaluar.pop()).doubleValue();
pilaEvaluar.push(new Double(a+b));
}
else if(tokenActual.equals("-")){//Si es resta se sacan dos valores y se restan (as铆 con todos los operadores)
b=((Double)pilaEvaluar.pop()).doubleValue();
a=((Double)pilaEvaluar.pop()).doubleValue();
pilaEvaluar.push(new Double(a-b));
}
else if(tokenActual.equals("*")){//Multiplicaci贸n
b=((Double)pilaEvaluar.pop()).doubleValue();
a=((Double)pilaEvaluar.pop()).doubleValue();
pilaEvaluar.push(new Double(a*b));
}
else if(tokenActual.equals("/")){//Divisi贸n
b=((Double)pilaEvaluar.pop()).doubleValue();
a=((Double)pilaEvaluar.pop()).doubleValue();
pilaEvaluar.push(new Double(a/b));
}
else if(tokenActual.equals("^")){//Potencia
b=((Double)pilaEvaluar.pop()).doubleValue();
a=((Double)pilaEvaluar.pop()).doubleValue();
pilaEvaluar.push(new Double(Math.pow(a,b)));
}
else if(tokenActual.equals("%")){//Resto de la divisi贸n entera
b=((Double)pilaEvaluar.pop()).doubleValue();
a=((Double)pilaEvaluar.pop()).doubleValue();
pilaEvaluar.push(new Double(a%b));
}
else if(tokenActual.equals("ln")){//Si es logaritmo natural s贸lo se saca un valor de la pila y se eval煤a
a=((Double)pilaEvaluar.pop()).doubleValue();
pilaEvaluar.push(new Double(Math.log(a)));
}
else if(tokenActual.equals("log")){//Logaritmo en base 10
a=((Double)pilaEvaluar.pop()).doubleValue();
pilaEvaluar.push(new Double(Math.log(a)/Math.log(10)));
}
else if(tokenActual.equals("abs")){//Valor absoluto
a=((Double)pilaEvaluar.pop()).doubleValue();
pilaEvaluar.push(new Double(Math.abs(a)));
}
else if(tokenActual.equals("rnd")){//Un n煤mero a random simplemente se mete en la pila de n煤meros
pilaEvaluar.push(new Double(Math.random()));
}
else if(tokenActual.equals("sen") || tokenActual.equals("sin")){ //Seno
a=((Double)pilaEvaluar.pop()).doubleValue();
pilaEvaluar.push(new Double(Math.sin(a)));
}
else if(tokenActual.equals("cos")){//Coseno
a=((Double)pilaEvaluar.pop()).doubleValue();
pilaEvaluar.push(new Double(Math.cos(a)));
}
else if(tokenActual.equals("tan")){//Tangente
a=((Double)pilaEvaluar.pop()).doubleValue();
pilaEvaluar.push(new Double(Math.tan(a)));
}
else if(tokenActual.equals("sec")){//Secante
a=((Double)pilaEvaluar.pop()).doubleValue();
pilaEvaluar.push(new Double(1/Math.cos(a)));
}
else if(tokenActual.equals("csc")){//Cosecante
a=((Double)pilaEvaluar.pop()).doubleValue();
pilaEvaluar.push(new Double(1/Math.sin(a)));
}
else if(tokenActual.equals("cot")){//Cotangente
a=((Double)pilaEvaluar.pop()).doubleValue();
pilaEvaluar.push(new Double(1/Math.tan(a)));
}
else if(tokenActual.equals("sgn")){//Signo
a=((Double)pilaEvaluar.pop()).doubleValue();
pilaEvaluar.push(new Double(sgn(a)));
}
else if(tokenActual.equals("asen") || tokenActual.equals("asin")){ //Arcoseno
a=((Double)pilaEvaluar.pop()).doubleValue();
pilaEvaluar.push(new Double(Math.asin(a)));
}
else if(tokenActual.equals("acos")){//Arcocoseno
a=((Double)pilaEvaluar.pop()).doubleValue();
pilaEvaluar.push(new Double(Math.acos(a)));
}
else if(tokenActual.equals("atan")){//Arcotangente
a=((Double)pilaEvaluar.pop()).doubleValue();
pilaEvaluar.push(new Double(Math.atan(a)));
}
else if(tokenActual.equals("asec")){//Arcosecante
a=((Double)pilaEvaluar.pop()).doubleValue();
pilaEvaluar.push(new Double(Math.acos(1/a)));
}
else if(tokenActual.equals("acsc")){//Arcocosecante
a=((Double)pilaEvaluar.pop()).doubleValue();
pilaEvaluar.push(new Double(Math.asin(1/a)));
}
else if(tokenActual.equals("acot")){//Arcocotangente
a=((Double)pilaEvaluar.pop()).doubleValue();
pilaEvaluar.push(new Double(Math.atan(1/a)));
}
else if(tokenActual.equals("senh") || tokenActual.equals("sinh")){//Seno hiperb贸lico
a=((Double)pilaEvaluar.pop()).doubleValue();
pilaEvaluar.push(new Double((Math.exp(a)-Math.exp(-a))/2));
}
else if(tokenActual.equals("cosh")){//Coseno hiperb贸lico
a=((Double)pilaEvaluar.pop()).doubleValue();
pilaEvaluar.push(new Double((Math.exp(a)+Math.exp(-a))/2));
}
else if(tokenActual.equals("tanh")){//tangente hiperb贸lica
a=((Double)pilaEvaluar.pop()).doubleValue();
pilaEvaluar.push(new Double((Math.exp(a)-Math.exp(-a))/(Math.exp(a)+Math.exp(-a))));
}
else if(tokenActual.equals("sech")){//Secante hiperb贸lica
a=((Double)pilaEvaluar.pop()).doubleValue();
pilaEvaluar.push(new Double(2/(Math.exp(a)+Math.exp(-a))));
}
else if(tokenActual.equals("csch")){//Cosecante hiperb贸lica
a=((Double)pilaEvaluar.pop()).doubleValue();
pilaEvaluar.push(new Double(2/(Math.exp(a)-Math.exp(-a))));
}
else if(tokenActual.equals("coth")){//Cotangente hiperb贸lica
a=((Double)pilaEvaluar.pop()).doubleValue();
pilaEvaluar.push(new Double((Math.exp(a)+Math.exp(-a))/(Math.exp(a)-Math.exp(-a))));
}
else if(tokenActual.equals("asenh") || tokenActual.equals("asinh")){ //Arcoseno hiperb贸lico
a=((Double)pilaEvaluar.pop()).doubleValue();
pilaEvaluar.push(new Double(Math.log(a+Math.sqrt(a*a+1))));
}
else if(tokenActual.equals("acosh")){//Arcocoseno hiperb贸lico
a=((Double)pilaEvaluar.pop()).doubleValue();
pilaEvaluar.push(new Double(Math.log(a+Math.sqrt(a*a-1))));
}
else if(tokenActual.equals("atanh")){//Arcotangente hiperb贸lica
a=((Double)pilaEvaluar.pop()).doubleValue();
pilaEvaluar.push(new Double(Math.log((1+a)/(1-a))/2));
}
else if(tokenActual.equals("asech")){//Arcosecante hiperb贸lica
a=((Double)pilaEvaluar.pop()).doubleValue();
pilaEvaluar.push(new Double(Math.log((Math.sqrt(1-a*a)+1)/a)));
}
else if(tokenActual.equals("acsch")){//Arcocosecante hiperb贸lica
a=((Double)pilaEvaluar.pop()).doubleValue();
pilaEvaluar.push(new Double(Math.log((sgn(a)*Math.sqrt(a*a +1)+1)/a)));
}
else if(tokenActual.equals("acoth")){//Arcocotangente hiperb贸lica
a=((Double)pilaEvaluar.pop()).doubleValue();
pilaEvaluar.push(new Double(Math.log((a+1)/(a-1))/2));
}
else if(tokenActual.equals("sqrt")){//Ra铆z cuadrada
a=((Double)pilaEvaluar.pop()).doubleValue();
pilaEvaluar.push(new Double(Math.sqrt(a)));
}
else if(tokenActual.equals("round")){//Redondear
a=((Double)pilaEvaluar.pop()).doubleValue();
pilaEvaluar.push(new Double(Long.toString(Math.round(a))));
}
else{//si es otra cosa tiene que ser un n煤mero, simplemente se mete en la pila
pilaEvaluar.push(Double.valueOf(tokenActual));
}
}//while
}
catch(EmptyStackException e){ //Si en alg煤n momento se acab贸 la pila hay un error
throw new ArithmeticException("EXPRESI脫N MAL PARSEADA");
}
catch(NumberFormatException e){ //Si hubo error al traducir un n煤mero hay un error
throw new ArithmeticException("EXPRESI脫N MAL DIJITADA");
}
catch(ArithmeticException e){ //Cualquier otro error de divisi贸n por cero o logaritmo negativo, etc.
throw new ArithmeticException("VALOR NO REAL EN LA EXPRESI脫N ");
}
a=((Double)pilaEvaluar.pop()).doubleValue(); //El valor a devolver
if(!pilaEvaluar.empty()) //Si todav铆a qued贸 otro valor en la pila hay un error
throw new ArithmeticException("EXPRESI脫N MAL DIJITADA");
return a;
}//funcion f
/**
*Esta funci贸n evalua la 煤ltima expresi贸n parseada en el valor x.
*@param x valor a evaluar.
*@return la evaluaci贸n del polinomio en el valor x.
*/
public double f(double x) throws ArithmeticException{
try{
return f(ultimaParseada,x);
}
catch(ArithmeticException e){
throw e;
}
}//Fin de la funcion f
//FUNCIONES PRIVADAS
/*
*saca Operador es una funci贸n que se encarga de sacar un operador de la pila
*y manejarlo de manera apropiada, ya sea un operador unario o binario
*/
private void sacaOperador(Stack Numeros, Stack operadores) throws EmptyStackException{
String operador, a, b;
final String operadoresBinarios="+ - * / ^ %"; //Lista de los operadores binarios
try{
operador=(String)operadores.pop(); //Saca el operador que se debe evaluar
if(operadoresBinarios.indexOf(operador)!=-1){ //Si es un operador binario saca dos elementos de la pila y guarda la operaci贸n
b=(String)Numeros.pop();
a=(String)Numeros.pop();
Numeros.push(new String(a+" "+b+" "+operador));
}
else{ //Sino s贸lo saca un elemento
a=(String)Numeros.pop();
Numeros.push(new String(a+" "+operador));
}
}
catch(EmptyStackException e){
throw e;
}
}//saca Operador
/*
*saca Operadores saca los operadores que tienen mayor prioridad y mete el nuevo operador
*/
private void sacaOperadores(Stack PilaNumeros, Stack PilaOperadores, String operador){
//Todas las funciones que se manejan como par茅ntesis de apertura
final String parentesis="( ln log abs sen sin cos tan sec csc cot sgn asen asin acos atan asec acsc acot senh sinh cosh tanh sech csch coth sqrt round asenh asinh acosh atanh asech acsch acoth";
//mientras la pila no est茅 vac铆a, el operador que sigue no sea un par茅ntesis de apertura, la longitud del operador sea uno (para que sea un operador), y la prioridad indique que tiene que seguir sacando elementos
while(!PilaOperadores.empty() && parentesis.indexOf((String)PilaOperadores.peek())==-1 && ((String)PilaOperadores.peek()).length()==1 && prioridad(((String)PilaOperadores.peek()).charAt(0))>=prioridad(operador.charAt(0))){
sacaOperador(PilaNumeros, PilaOperadores); //Saca el siguiente operador
}
PilaOperadores.push(operador);//Al final mete el nuevo operador luego de sacar todo lo que ten铆a que sacar.
}
/*
*Funci贸n que devuelve la prioridad de una operacion
*/
private int prioridad(char s) {
if (s=='+' || s=='-') //Si es una suma o una resta devuelve cero
return 0;
else if (s=='*' || s=='/' || s=='%') //Si es multiplicaci贸n, divisi贸n o resto de divisi贸n devuelve uno
return 1;
else if (s=='^')//Si es potencia devuelve dos
return 2;
return -1; //Si no fue nada de lo anterior devuelve -1
} //Fin de la funcion prioridad
/*
*Funci贸n que pregunta si un caracter es un n煤mero o no
*/
private boolean isNum(String s) {
if (s.compareTo("0")>=0 && s.compareTo("9")<=0) //Si el caracter est谩 entre 0 y 9 (si es un n煤mero)
return true;
else
return false;
} //Fin de la funcion isNum
/*
*Quita los espacios del String con el polinomio
*/
private String quitaEspacios(String polinomio){
String unspacedString = ""; //Variable donde lee la funci贸n
for(int i = 0; i < polinomio.length(); i++){ //Le quita los espacios a la espresi贸n que ley贸
if(polinomio.charAt(i) != ' ') //Si el caracter no es un espacio lo pone, sino lo quita.
unspacedString += polinomio.charAt(i);
}//for
return unspacedString;
}//quitaEspacios
/*
*Devuelve el signo del n煤mero dado
*/
private double sgn(double a){
if(a<0) //Si el n煤mero es negativo devuelve -1
return -1;
else if(a>0)//Si es positivo devuelve 1
return 1;
else//Si no es negativo ni positivo devuelve cero
return 0;
}
//CLASES PRIVADAS
//Clase SintaxException
//Esta es la excepci贸n que se lanza si hay alg煤n error sint谩ctico en la expresi贸n
private class SintaxException extends ArithmeticException{ //En realidad extiende la ArithmeticException
public SintaxException(){ //Si se llama con el mensaje por defecto
super("ERROR EN LA SINTAXIS HAZLO BIEN DEL POLINOMIO SIGUE INTENTANDO "); //El constructor llama a la clase superior
}
public SintaxException(String e){ //si se llama con otro mensaje
super(e); //El constructor llama a la clase superior
}
}
}//fin de Parseador
import java.applet.*;
import java.awt.*;
public class PruebaParseador extends java.applet.Applet {
Parseador miparser=new Parseador(); //Constructor del parseador
String expresion=new String(); //Expresi贸n a parsear
double valor=0; //Valor en el que se va a evaluar
TextField inputexpresion = new TextField("x + 5"); //Textfield donde se digita la expresi贸n a parsear
TextField inputvalor = new TextField("0",5); //Textfield donde se digita el valor a evaluar en la expresi贸n
Button boton= new Button("EVALUAR LA EXPRECION MATEMATICA"); //Bot贸n para evaluar
TextField outputparseo = new TextField(" "); //Resultado de parsear la expresi贸n
TextField outputevaluar = new TextField(" "); //Resultado de la evaluaci贸n en la expresi贸n
Label info = new Label(" U N I V E R S I D A D I C E L C O M P I L A D O R P U T O C A R L O S ", Label.CENTER); //Label donde se dan los errores
public void init(){ //Todo se pone en el applet
add(inputexpresion);
add(inputvalor);
add(boton);
add(outputparseo);
add(outputevaluar);
add(info);
}//init
public boolean action(Event evt, Object arg){
if (evt.target instanceof Button){ //Si se apret贸 el bot贸n
try{
info.setText(""); //Se pone el Label de los errores vac铆o
expresion=inputexpresion.getText(); //Se lee la expresi贸n
valor=Double.valueOf(inputvalor.getText()).doubleValue(); //Se lee el valor a evaluar
outputparseo.setText(miparser.parsear(expresion)); //Se parsea la expresi贸n
outputevaluar.setText(""+redondeo(miparser.f(valor),5)); //Se eval煤a el valor y se redondea
}
catch(Exception e){ //Si hubo error lo pone en el Label correspondiente
info.setText(e.toString());
}
}//if del bot贸n
return true;
}//action
/*
*Se redondea un n煤mero con los decimales dados
*/
private double redondeo(double numero, int decimales){
return ((double)Math.round(numero*Math.pow(10,decimales)))/Math.pow(10,decimales);
}
}//PolCero
