Академический Документы
Профессиональный Документы
Культура Документы
Para trabajos de programacin aplicada, como por ejemplo para clculos numricos, aveces hacemos uso de funciones matematicas, ya sean lineales, cuadrticas, cubicas, trigonomtricas etc. Y nos encontramos en la necesidad de poder analizar en valor de una funcin especifica, en el caso de ser una solo funcin no habra problemas, pero en el caso de ser cualquier funcin nos encontramos en la necesidad de quizs expresar la funcin de la forma mas conocida, como por ejemplo para funciones cuatraticas la podramos escribir del siguiente modo:
'
yf(x)=ax2+bx+c En un programa la escribiramos del siguiente modo Yf(x)=ax ^2+bx+c O bien para una funcin trigonomtrica Yf(x)=sen(ax ^2)+bx+tan c
Para escribirlas de ese modo necesitamos una clase o algo parecido, que nos pueda aceptar tal expresin y poder calcular el valor de la funcin segn el valor de x que le demos. En este post se describir una clase que hace tal tarea, osea podemos eviarle a la clase una expresin como la anterior, con un valor de x, y que la misma me realice el calculo. El cdigo a continuacin es el cdigo de la clase Funcion
package funciones; import import import import import import /** * java.util.ArrayList; java.util.regex.Matcher; java.util.regex.Pattern; javax.script.ScriptEngine; javax.script.ScriptEngineManager; javax.script.ScriptException;
* @author RAFAEL */ public class Funcion { private String operacion; private String resultadoConversion; private String resultadoOperacion; private int indiceIni; private int indiceFin; private String valor; public Funcion() { } public String evaluar( String operacion, String valor){ this.operacion=operacion; this.valor=valor; this.resultadoConversion=analizaCadena(this.operacion); this.resultadoConversion=reemplazaOperacionJS(this.resultadoConversion); return this.resultadoOperacion=calculo(this.resultadoConversion); } private String analizaCadena(String cadena){ cadena=cadena.replaceAll("x", this.valor); cadena=quitarEspacios(cadena); cadena="-"+cadena; char[] vectorCadena=cadena.toCharArray(); if(cadena.contains("^")){ cadena=reemplazaPotencia(vectorCadena, cadena); } vectorCadena=cadena.toCharArray(); if(cadena.contains("cos")){ cadena=reemplazaTrigonometrica(vectorCadena, cadena, ".co",'c'); } vectorCadena=cadena.toCharArray(); if(cadena.contains("sen")){ cadena=reemplazaTrigonometrica(vectorCadena, cadena, ".si",'s'); } vectorCadena=cadena.toCharArray(); if(cadena.contains("tan")){ cadena=reemplazaTrigonometrica(vectorCadena, cadena, ".ta",'t'); } return cadena; } private String reemplazaParIzq(char[] cadena,int indice){ ArrayList<Character> lista1=new ArrayList<Character>(); ArrayList<Character> lista2=new ArrayList<Character>(); String res=""; int i; for ( i = indice-1; i >=0; i--) { if(cadena[i]==')'){ lista1.add(cadena[i]); } else { if(cadena[i]=='('){ lista2.add(cadena[i]); } } res+=cadena[i]; if((lista1.size()==lista2.size())&&(i!=(indice-1))){ this.indiceIni=i; return invertir(res); }
} return null; } private String reemplazaParDer(char[] cadena,int indice ){ ArrayList<Character> lista1=new ArrayList<Character>(); ArrayList<Character> lista2=new ArrayList<Character>(); String res=""; int i; for ( i = indice+1; i <cadena.length ; i++) { if(cadena[i]=='('){ lista1.add(cadena[i]); } else { if(cadena[i]==')'){ lista2.add(cadena[i]); } } res+=cadena[i]; if((lista1.size()==lista2.size())&&(i!=(indice+1))){ this.indiceFin=i+1; return res; } } return null; } private String reemplazaNumIzq(char[] cadena,int indice){ Pattern exp= Pattern.compile("\\\\d|\\\\."); Matcher expReg; String resultadoBase =""; String res = ""; for (int i = indice-1; i >=0; i--) { res=""; res+=cadena[i]; expReg=exp.matcher(res); if (expReg.find()){ resultadoBase+=cadena[i]; this.indiceIni=i; } else { break; } } return invertir(resultadoBase); } private String reemplazaNumDer(char[] cadena,int indice){ Pattern exp= Pattern.compile("\\\\d|\\\\."); Matcher expReg; String resultadoBase =""; String res = ""; for (int i = indice+1; i<cadena.length; i++) { res=""; res+=cadena[i]; expReg=exp.matcher(res); if (expReg.find()){ resultadoBase+=cadena[i]; this.indiceFin=i+1; } else { break; }
} return resultadoBase; } private String invertir(String cadena){ char[] vector=cadena.toCharArray(); String res=""; for (int i = vector.length-1; i >=0; i--) { res+=vector[i]; } return res; } private String reemplazaPotencia(char[] vectorCadena,String cadena){ String resIzq="",resDer=""; for (int indice = 0; indice < vectorCadena.length; indice++) { if (vectorCadena[indice]=='^') { if (vectorCadena[indice - 1] == ')') { resIzq =reemplazaParIzq(vectorCadena, indice); } else{ resIzq =reemplazaNumIzq(vectorCadena, indice); } if (vectorCadena[indice + 1] == '(') { resDer =reemplazaParDer(vectorCadena, indice); } else{ resDer =reemplazaNumDer(vectorCadena, indice); } vectorCadena=(cadena.substring(0,this.indiceIni)+".po(" +resIzq+","+resDer+")"+(cadena.substring(this.indiceFin,cadena.length()))).toCha rArray(); cadena=(cadena.substring(0,this.indiceIni)+".po(" +resIzq+","+resDer+")"+(cadena.substring(this.indiceFin,cadena.length()))); indice=0; } } return cadena; } private String reemplazaTrigonometrica(char[] vectorCadena,Stringcadena,String op eracion,char caracter){ String resDer=""; for (int indice = 0; indice < vectorCadena.length; indice++) { if((vectorCadena[indice]==caracter)&&((vectorCadena)[indice1]!='.')&&(indice!=0)){ if (vectorCadena[indice + 3] == '(') { resDer =reemplazaParDer(vectorCadena, indice+2); } else{ resDer =reemplazaNumDer(vectorCadena, indice+2); } vectorCadena=(cadena.substring(0,indice)+operacion+"(" +resDer+")"+(cadena.substring(this.indiceFin,cadena.length()))).toCharArray(); cadena=(cadena.substring(0,indice)+operacion+"(" +resDer+")"+(cadena.substring(this.indiceFin,cadena.length())) ); indice=0; } }
return cadena; } public String getResultadoConversion() { return this.resultadoConversion; } public String getResultadoOperacion() { return resultadoOperacion; } private String quitarEspacios(String sTexto){ String sCadenaSinBlancos=""; for (int x=0; x < sTexto.length(); x++) { if (sTexto.charAt(x) != ' ') sCadenaSinBlancos += sTexto.charAt(x); } return sCadenaSinBlancos; } private String reemplazaOperacionJS(String operacion){ this.resultadoConversion=operacion.replaceAll(".po","Math.pow"); this.resultadoConversion=this.resultadoConversion.replaceAll(".co","Math.cos"); this.resultadoConversion=this.resultadoConversion.replaceAll(".si","Math.sin"); this.resultadoConversion=this.resultadoConversion.replaceAll(".ta","Math.tan"); return this.resultadoConversion.substring(1,this.resultadoConversion.length()); } private String calculo(String cadena) { ScriptEngineManager script = new ScriptEngineManager(); ScriptEngine js = script.getEngineByName("JavaScript"); try{ return js.eval(cadena).toString(); }catch(Exception e){ return e.toString(); } } }
Mtodo que evalua la cadena "operacion" que contiene la funcion a analizar con el valor "valor", este al igual que el metodo acceso de la propiedad resultado
Mtodo que me analiza la cadea recibida del constructor, en este se evalua el contenido de la misma, es decir si existe una potencia, o una funcin trigonomtrica.
Recibe un array conteniendo la operacin y a partir del ndice recibido de evalua hasta donde es el alcance de la operacin contenida dentro de los parentesis. Es decir si recibe una array conteniendo (sen (1)-2+3) ^8 devuelve (sen(1)2+3)
Igual a la anterior pero evalua el alcance pero por la derecha, es decir en una potencia devuelve el exponente.
En el caso de no haber parntesis, evalua el alcance pero de los nmeros que contiene la operacin, por ejemplo si la operacin es 233.4^8 devuelve 233.4
Si existe una potencia, este mtodo es el indicado para realizar la conversin,es decir Si en la cadena existe 233.4^8 lo reemplaza por .po(233.4,8) para ser evaluada luego.
Reemplaza las funciones trigonomtricas, es decir si en la operacin llega sen (3), la reemplaza por .si(3), para luego ser evaluada.
para este caso Utilizamos la libreria de JavaScript incorporada en java, asi que reemplazamos para que este lenguaje la pueda analizar, como ser si viene en la cadena .si (3), lo reemplazamos por Math.sin(3)
una vez analizada toda la cadena, se procede con este metodo a realizar el calculo, para ello hacemos uso de javascript (ver este post para mas informacion). La sintaxis para utilizar esta clase es la siguiente
Ahora crearemos un proyecto Java en Netbeans,y en nuestro Main incluimos las siguientes lneas para probar las funciones escritas anteriormente. En todos los ejemplos observamos que instanciamos la clase Funcion, llamamos el metodo evaluar, y luego mostramos por la salida estndar la conversin que realiza la clase y el valor de la funcin. El constructor es inicializado, con la cadena que contiene la operacin, mas el valor que le vamos a dar al valor de x. Probamos la potencia
import javax.script.ScriptException; public class Main { public static void main(String[] args) throws ScriptException { String cadena="3^x+32+4^(2+x)";// Funcion f=new Funcion(); f.evaluar(cadena, "2"); System.out.println(f.getResultadoConversion()); System.out.println(f.getResultadoOperacion());
} }
El resultado es
Probamos la raz
import javax.script.ScriptException; public class Main { public static void main(String[] args) throws ScriptException { String cadena="x^(1/2)"; Funcion f=new Funcion(); f.evaluar(cadena, "144"); System.out.println(f.getResultadoConversion()); System.out.println(f.getResultadoOperacion()); System.out.println(Math.cos(1)); } }
La salida es
import javax.script.ScriptException; public class Main { public static void main(String[] args) throws ScriptException { String cadena="sen(34*2)+tan x"; Funcion f=new Funcion(); f.evaluar(cadena, "1"); System.out.println(f.getResultadoConversion()); System.out.println(f.getResultadoOperacion()); System.out.println(Math.cos(1)); } }
La salida es
import javax.script.ScriptException; public class Main { public static void main(String[] args) throws ScriptException { String cadena="sen (34*x)+tan 1+32+x^(2+4-cos 3)"; Funcion f=new Funcion(); f.evaluar(cadena, "1.5"); System.out.println(f.getResultadoConversion()); System.out.println(f.getResultadoOperacion()); System.out.println(Math.cos(1)); } }
El resultado obtenido
Bien con esto terminamos, vimos la clase Funcion que nos puede resolver problemas que nos pueden aparecer como mencionamos en los mtodos numricos hasta pronto
'