Pregunta

Me gustaría saber si alguien tiene información o experiencia sobre cómo hacer algo que suena simple, pero no parece que cuando se trata de programarlo. La idea es: dar una cadena que contiene una ecuación, como por ejemplo: "2 * x = 10", por ejemplo (esto es simple, pero podría llegar a estar muy compleja, como sqrt (54) * 35 = x ^ 2; y así en ....) y el programa volvería x = 5 y posiblemente dará un registro de cómo llegó hasta allí.

Es esto factible? Si es así, ¿alguien tiene una ventaja? Para información existe este sitio ( http://www.numberempire.com/equationsolver.php ), que hace lo mismo que en PHP, pero no es de código abierto.

Gracias por cualquier ayuda!

¿Fue útil?

Solución

Esto se llama "análisis", y aunque la informática ya ha resuelto este problema no es simple en absoluto hasta que comprenda a fondo. Hay toda una disciplina informática que describe la forma de resolver este problema. En C se debe definir la gramática de su entrada (posiblemente con reglas de prioridad en ella), a continuación, realizar análisis léxico en su entrada, a continuación, de análisis el resultado y, finalmente, evaluar su análisis sintáctico árbol.

En lenguajes como Ruby, sin embargo, porque usted tiene este tipo de apoyo a fondo para la manipulación de cadenas y porque tiene un poder tan enorme tiempo de ejecución puede resolver su problema con una sola línea de código, así:

puts(eval($_)) while gets

Sí, que cubrirá más de lo que pides.

Otros consejos

En primer lugar hay que definir adecuadamente qué tipo de ecuaciones que pueden tener como entrada. A continuación, se debe crear una buena abstracción para representar la ecuación, por ejemplo, una clase de polinomios. Cuando se desea utilizar la expresión más compleja, ir a por un árbol de expresiones numéricas. El análisis puede ser muy fácil si usted tiene buenas reglas para convertir la expresión en notación de prefijo, entonces la evaluación es muy fácil usando pilas. Una vez que tenga árboles artithmetic o polinomios, se puede aplicar transformaciones para calcular la variable (s).

Si ecuaciones no se complican, no será seguramente pocas líneas de código C / C ++.

Para las ecuaciones lineales, que tendría que simular uno de los métodos descritos en los libros de álgebra lineal. El código de que es lo suficientemente pequeño.

Usted podría intentar vincular en sympy a su código C (o C ++) y utilizarlo para resolver sus ecuaciones.

IIRC, sympy tiene ese tipo de funcionalidad. Además, debería ser más fácil de manipular la cadena de entrada a una ecuación en el interior útil de Python y luego hacerlo pasar a sympy para la solución.

No va a ser dos partes para su problema: el análisis de la ecuación (s), y resolverlos de manera simbólica. No voy a decir mucho sobre la primera, ya que otras respuestas ya han cubierto bien ese tema; mi recomendación personal sería escribir un simple analizador descendente recursivo de expresiones en notación de prefijo.

La segunda parte, la resolución de ecuaciones analíticamente, va a ser complicado. En términos generales, hay clases especiales de ecuaciones para los que existen métodos estándar para encontrar una solución analítica:

  • Sistemas de ecuaciones lineales: cualquier solver lineal directa. Si desea mostrar los pasos de forma explícita y el número de ecuaciones / incógnitas es pequeño, me gustaría recomendar algo tan simple como la eliminación de Gauss no girados o la regla de Cramer.
  • Sistema de ecuaciones polinómicas: equivalente, después de la sustitución de variables, a la búsqueda de las raíces de los polinomios individuales. Si estos tienen grado <= 4, hay fórmulas para las soluciones exactas. NB: Para grado 3 y 4 estas fórmulas no son agradables
  • .
  • soluciones racionales a un sistema de ecuaciones polinómicas con coeficientes racionales: Do variable de sustitución que el anterior. A continuación, la fuerza bruta usando la prueba de cero racional.
  • Otros tipos de ecuaciones: Buena suerte. Para obtener más complicados sistemas [de] ecuaciones no lineales, si se puede conformarse con soluciones numéricas (no analíticas), mira en el método de Newton.

Una corrección: este no es el álgebra lineal, que por lo general significa matrices de de múltiples ecuaciones e incógnitas

.

Su ejemplo no es ciertamente compleja.

Lo que necesita es una gramática de expresión simple y analizador. Analizar la ecuación en un árbol de sintaxis abstracta y recorrer el árbol de evaluarlo.

Si estuviera escribiendo Java puede ser que parezca esta . Otro ejemplo es symja . Tal vez va a ser suficiente inspiración para que usted pueda llegar con su propia para C ++.

También puede que desee ver en Mathematica y Wolfram Alpha. Stephen Wolfram es uno de los mejores matemáticos del mundo e informáticos. Él tiene un montón de cosas que se puede volver a utilizar en una gran ventaja en lugar de escribir por sí mismo.

Se tendrá que definir lo que entendemos por "resolver" y lo que espera haber vuelto.

Hay soluciones simbólicas y soluciones numéricas. ¿A cuál te refieres? Ambos son igualmente válidas, pero son diferentes. Vamos a aplicar diferentes técnicas en función de su respuesta.

Otro punto: hay muchas técnicas para "resolver" ecuaciones que dependen en gran medida del tipo de ecuación. Si me das algo así como f(x) = 0 pienso en los algoritmos de cálculo de raíces como el método de Newton. Si me das una ecuación diferencial ordinaria que podría intentar un método de sustitución o integración numérica usando Runge-Kutta. Si me das una ecuación diferencial parcial puedo aplicar diferencias finitas, elementos finitos, o técnicas de elementos de contorno. (No me refiero a elípticas, parabólicas, hiperbólicas y PDE).

El punto es que su pregunta es muy genérico, y la respuesta depende en gran medida de lo que estás tratando de hacer. Más detalle puede ayudar.

En general, usted tendrá que analizar la expresión en alguna representación interna. Muchos libros de álgebra lineal sugieren el uso de matrices (o std::vector) para representar los coeficientes. El exponente del término se define por su posición en el vector.

Así, por ejemplo, la expresión:

 2 + 3x + 5x^2

puede representarse como una matriz o std::vector:

std::vector<int> expression;
expression[0] = 2; // 2 * x ^ 0
expression[1] = 3;
expression[2] = 5;

Escribir una función de evaluación se vuelve trivial, y deja como ejercicio para el lector.

Solución de ecuaciones múltiples se vuelve más compleja. Hay bibliotecas existentes y algoritmos para esto. Una búsqueda en Google debería llegar a algo bueno. : -)

Sugiero comenzar con términos sencillos y la construcción de un analizador para eso. Una vez que las obras, se puede cambiar el analizador para aceptar los nombres de función también.

Si usted está tratando de simplificar una expresión que contiene los términos de ambos lados de la =, simplemente anote los pasos que tomaría normalmente cuando la solución a mano. Pruebe algunas ecuaciones diferentes para obtener algunas reglas abajo. Ahora aplicar estas normas en C ++.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top