[C con Clase] Dar una función matemática por teclado.

Steven Davidson steven en conclase.net
Jue Feb 22 22:15:34 CET 2007


Hola Daniel,

El pasado 2007-02-22 17:33:16, dani escribió:

d> Hola a todos, 
d> mirad me gustaría hacer un programa que supiera trabajar con funciones matemáticas tipo sin(x), exp(x), etc, pero que fuese el usuario quien las escribiese por teclado y el programa las interpretase. Yo soy nuevo en c++ y ni si quiera se me ocurre como se podría hacer esto, así que si alguien me da unas pistas de como se hace o algún manual (pequeñito :-)) pues se lo agradecería.

La verad es que te has contestado tú mismo a tu inquietud. La palabra clave es "interpretar", que es exactamente lo que tienes que hacer. Ten presente que toda la información introducida por el usuario es en forma de cadenas de caracteres. Si requieres valores numéricos, entonces tendrás que interpretarlos. Como puede ser algo complicado, por eso usamos las funciones y/o clases estándares para despreocuparnos de estas tareas.

En tu caso, vas a tener que hacer algo parecido. Tendrás que ir comprobando si el usuario ha escrito la palabra "sen", "cos", "exp", "log", "ln", etc.. Por ejemplo, el usuario puede escribir:

sen 12

Recibirás esta información en forma de cadena de caracteres. Tendrás que procesar la cadena comprobando subcadenas y aplicando ciertos cirterios. Esto implica un formato que necesitas diseñar, que puede ser por ejemplo,

<función> <número>

Tendrás que comparar la primera subcadena con una lista de nombres de funciones para validar la expresión escrita por el usuario. Por ejemplo,

const char funciones[6][4] = { "sen", "cos", "tan", "log", "ln", "exp" };

Para comparar, usaremos 'strcmp()'. Con aterioridad, necesitamos conseguir la subcadena sin el resto de los caracteres. Esto supone que leemos hasta el primer espacio que nos encontremos. Si usamos 'cin >>', esto es más sencillo, ya que hace justamente esto por defecto. Por ejemplo,

char szCad[4]="";
double fNum;

cin >> szCad >> fNum;

Luego, comprobamos si 'szCad' se refiere a una de las funciones conocidas:

int nIndice = -1;

for( int i=0; i<6 && -1 == nIndice; i++ )
  if( !strcmp( szCad, funciones[i] )
    nIndice = i;

double resultado = 0.0;

// Si 'nIndice' es un índice válido, entonces aplicamos la función encontrada
if( nIndice != -1 )
  switch( nIndice )
  {
    case 0:
      resultado = sin( fNumero );
    break;

    case 1:
      resultado = cos( fNumero );
    break;

    case 2:
      resultado = tan( fNumero );
    break;

    case 3:
      resultado = log10( fNumero );
    break;

    case 4:
      resultado = log( fNumero );
    break;

    case 5:
      resultado = exp( fNumero );
    break;
  }

Hay que tener que algunas funciones no funcionarán siempre, como es el caso de los logaritmos, ya que el parámetro debe ser positivo; o sea, mayor de cero.

Ahora bien, hay que tener en cuenta la posibilidad de introducir expresiones más complejas, como por ejemplo, el usuario escribe:

? sen 12 + cos 43
? tan ln 23

Posiblemente querrás aceptar paréntesis para agrupar ciertas operaciones. Por ejemplo,

? cos ( 3.45 * exp ( -23.98 / tan ( 7.8 ) ) + ln ( 2.001 ) )

Esto ya complica más la situación, porque la lógica de los paréntesis cambia el orden de las operaciones, al igual que los operadores aritméticos: +, -, *, /, etc..

La verdad es que si quieres algo más complejo, realmente te estás metiendo en el área de lingüística. Podríamos considerar que tu formato representa un lenguaje, con su propia gramática. Para ello, podemos aplicar ciertas reglas y metodologías de diseño para analizar y validar cualesquier expresiones escritas por el usuario. Si quieres saber más de esto, háznoslo saber.


Espero que todo esto te sirva.

Steven


Más información sobre la lista de distribución Cconclase