potencia - raiz cuadrada en c++
Añadiendo el! operador y sqrt(), pow() etc. a una aplicación de ejemplo de calculadora (4)
Es más fácil trabajar con clases derivadas y funciones virtuales: cada clase especializada lee su propia entrada ...
class base{public:
virtual double calc()=0;
};
class get_sqrt:public base{
int useless;
public:
virtual double calc(){cin>>number;return sqrt(number);}
}get_sqrt;
Ahora los organizamos en un mapa, solo usaremos sus punteros:
map<string,base*> func;
func["sqrt"]=&get_sqrt;
También hay un método especializado que solo mira al siguiente personaje: peek ();
char c=cin.peek();
Usted puede deshacerse del interruptor usando 1 if y poniendo! + - ... en func; (Deben operar en left_param por simplicidad
if (c>=''0''&&c<=''9'') cin>>right_param; //get a number, you don''t have to put the character back as it hasn''t been removed
else{string s; cin>>s;right_param=func[s]->calc();}
Básicamente, hay algún tipo de punteros de función, pero sin la sintaxis desordenada y en la que puedes almacenar datos entre los cálculos.
Edición: pensé en el problema de los espacios en blanco; se puede agregar antes de que comience a calcular, también creo que podría haber una manera de establecer diferentes separadores, como números, pero no sé cómo.
Estoy haciendo los ejercicios en el nuevo libro de Stroustrup "Principios y práctica de programación utilizando C ++" y me preguntaba si alguien en SO lo ha hecho y está dispuesto a compartir el conocimiento. Específicamente sobre la calculadora que se desarrolló en los capítulos 6 y 7. Por ejemplo, las preguntas sobre la adición de! operador y sqrt (), pow () etc. He hecho esto, pero no sé si la solución que tengo es la "buena" forma de hacer las cosas, y no hay soluciones publicadas en el sitio web de Bjarne. Me gustaría saber si voy por el camino correcto. ¿Tal vez podamos hacer un wiki para los ejercicios?
Básicamente tengo un analizador de fichas. Se lee una char a la vez de cin. Está destinado a tokenizar expresiones como 5 * 3 + 1 y funciona muy bien para eso. Uno de los ejercicios es agregar una función sqrt (). Así que modifiqué el código de tokenising para detectar "sqrt (" y luego devolví un objeto Token que representa a sqrt. En este caso, uso el ''s'' del char. La declaración del caso se ensuciaría.
char ch;
cin >> ch; // note that >> skips whitespace (space, newline, tab, etc.)
switch (ch) {
case '';'': // for "print"
case ''q'': // for "quit"
case ''('':
case '')'':
case ''+'':
case ''-'':
case ''*'':
case ''/'':
case ''!'':
return Token(ch); // let each character represent itself
case ''.'':
case ''0'': case ''1'': case ''2'': case ''3'': case ''4'':
case ''5'': case ''6'': case ''7'': case ''8'': case ''9'':
{
cin.putback(ch); // put digit back into the input stream
double val;
cin >> val; // read a floating-point number
return Token(''8'',val); // let ''8'' represent "a number"
}
case ''s'':
{
char q, r, t, br;
cin >> q >> r >> t >> br;
if (q == ''q'' && r == ''r'' && t == ''t'' && br == ''('') {
cin.putback(''(''); // put back the bracket
return Token(''s''); // let ''s'' represent sqrt
}
}
default:
error("Bad token");
}
Movería la detección ''sqrt'' a otro método para la detección de funciones. Esencialmente, eliminaría la detección de ''s'' y agregaría algo dentro del caso predeterminado que leería la cadena hasta un ''(''.
Si no se detecta ''('', se produce un error.
Si leíste correctamente una cadena, pásala a un analizador de nombres de funciones que utiliza comparaciones de cadenas para generar un token que represente una llamada a sqrt o sin o la función que quieras. El método que comprueba los nombres de las funciones también puede generar un error si lee una cadena que no reconoce.
Pensé que un mapa de cadenas para punteros de función podría ser una forma concisa de representar cosas como sqrt, sin, cos, etc. que toman un doble simple y devuelven un doble:
map<std::string, double (*)(double)> funcs;
funcs["sqrt"] = &sqrt;
funcs["sin"] = &sin;
funcs["cos"] = &cos;
Luego, cuando el analizador detecta una cadena (str) correcta, puede llamar a la función con un argumento (arg) así:
double result = funcs[str](arg);
Con este método, una sola llamada puede manejar todos los casos de funciones (de ese tipo).
En realidad, no estoy seguro de que esa sea la sintaxis correcta, ¿alguien puede confirmar?
¿Parece esto un método útil?
Hay pocas soluciones publicadas en Stroustrup - Programación y más vendrán con el tiempo.
Intente resolver ejercicios solo con las características del lenguaje y las instalaciones de la biblioteca presentadas hasta ahora en el libro; los usuarios novatos no pueden hacer nada más. Luego regresa más tarde para ver cómo se puede mejorar una solución.