Entendimiento moderno de la recursividad: definición de funcionalidad y acceso a la misma desde fuera y desde esta funcionalidad. Se cree que la recursividad nació de los matemáticos: cálculo factorial, series infinitas, fractales, fracciones continuas… Sin embargo, la recursividad se puede encontrar en todas partes. Las leyes naturales objetivas “consideran” la recursividad como su principal algoritmo y forma de expresión (existencia) no tanto de los objetos del mundo material, sino en general el principal algoritmo de movimiento.
Personas de diversas especialidades en diversos campos de la ciencia y la tecnología utilizan el algoritmo recursivo f (x), donde "x ~/=f (x)". Una función que se llama a sí misma es una solución sólida, pero formar y comprender esta solución es, en la mayoría de los casos, una tarea muy difícil.
En la antigüedad, la recursividad se usaba para aumentar el espacio del palacio. A través de un sistema de espejos dirigidos entre sí, puede crear impresionantes efectos espaciales tridimensionales. Pero, ¿es tan fácil entender cómoajustar estos espejos? Es aún más difícil determinar dónde está un punto en el espacio, reflejado a través de varios espejos.
Recursión, algoritmos recursivos: significado y sintaxis
El problema, que se formula repitiendo una secuencia de operaciones, se puede resolver recursivamente. Un algoritmo simple (calcular una ecuación cuadrática, un script para llenar una página web con información, leer un archivo, enviar un mensaje…) no requiere recursividad.
Principales diferencias del algoritmo que permite una solución recursiva:
- hay un algoritmo que debe ejecutarse varias veces;
- algoritmo necesita datos que cambian cada vez;
- el algoritmo no tiene que cambiar cada vez;
- hay una condición final: el algoritmo es recursivo, no infinito.
En general, no se puede argumentar que la ejecución única es una condición necesaria para la ausencia de una razón para la recursividad. Tampoco puede exigir una condición final obligatoria: las recursiones infinitas tienen su propio alcance.
El algoritmo es recursivo: cuando una secuencia de operaciones se realiza repetidamente, sobre datos que cambian cada vez y dan un nuevo resultado cada vez.
Fórmula recursiva
La comprensión matemática de la recursividad y su análogo en la programación son diferentes. Matemáticas, aunque hay signos de programación, pero la programación es matemática de un orden mucho más alto.
Un algoritmo bien escrito es como un espejo del intelecto de su autor. Generalla fórmula de recurrencia en programación es "f(x)", donde "x ~/=f(x)" tiene al menos dos interpretaciones. Aquí "~" es la similitud o ausencia del resultado, y "=" es la presencia del resultado de la función.
Primera opción: dinámica de datos.
- la función "f(x)" tiene un algoritmo recursivo e inmutable;
- "x" y el resultado "f(x)" tienen valores nuevos cada vez, el resultado "f(x)" es el nuevo parámetro "x" de esta función.
Segunda opción: dinámica de código.
- la función "f(x)" tiene varios algoritmos que refinan (analizan) los datos;
- análisis de datos - una parte del código y la implementación de algoritmos recursivos que realizan la acción deseada - la segunda parte del código;
- el resultado de la función "f(x)" no lo es.
Ningún resultado es normal. La programación no es matemática, aquí el resultado no tiene por qué estar explícitamente presente. Una función recursiva puede simplemente analizar sitios y llenar la base de datos, o instanciar objetos de acuerdo con la entrada entrante.
Datos y recursividad
La programación de algoritmos recursivos no se trata de calcular un factorial, en el que la función recibe cada vez un valor dado que es uno más o menos que uno; la opción de implementación depende de la preferencia del desarrollador.
¡No importa cómo sea el factorial "8!",algoritmo que sigue estrictamente esta fórmula.
El procesamiento de información es "matemática" de un orden completamente diferente. Las funciones recursivas y los algoritmos aquí operan en letras, palabras, frases, oraciones y párrafos. Cada siguiente nivel usa el anterior.
El flujo de datos de entrada se analiza en una amplia gama de condiciones, pero el proceso de análisis generalmente es recursivo. No tiene sentido escribir algoritmos únicos para todas las variantes del flujo de entrada. Debe haber una funcionalidad. Aquí, los algoritmos recursivos son ejemplos de cómo formar un flujo de salida que sea adecuado para la entrada. Esta no es la salida del algoritmo recursivo, pero es la solución deseada y necesaria.
Abstracción, recursividad y POO
La programación orientada a objetos (POO) y la recursividad son entidades fundamentalmente diferentes, pero se complementan perfectamente. La abstracción no tiene nada que ver con la recursividad, pero a través de la lente de la programación orientada a objetos crea la posibilidad de implementar la recursividad contextual.
Por ejemplo, la información se analiza y las letras, palabras, frases, oraciones y párrafos se res altan por separado. Obviamente, el desarrollador preverá la creación de instancias de objetos de estos cinco tipos y ofrecerá una solución de algoritmos recursivos en cada nivel.
Mientras tanto, si en el nivel de las letras “no tiene sentido buscar el significado”, entonces la semántica aparece en el nivel de las palabras. Puedes dividir palabras en verbos, sustantivos, adverbios, preposiciones… Puedes ir más allá y definir casos.
A nivel de frase, la semántica se complementa con signos de puntuación y lógicaCombinación de palabras. En el nivel de las oraciones se encuentra un nivel de semántica más perfecto, y un párrafo puede ser considerado como un pensamiento completo.
El desarrollo orientado a objetos predetermina la herencia de propiedades y métodos y propone iniciar la jerarquía de objetos con la creación de un ancestro completamente abstracto. Al mismo tiempo, sin duda, el análisis de cada descendiente será recursivo y no diferirá demasiado a nivel técnico en muchas posiciones (letras, palabras, frases y oraciones). Los párrafos, como pensamientos completos, pueden sobresalir de esta lista, pero no son la esencia.
Es importante que la mayor parte del algoritmo se pueda formular a nivel de ancestro abstracto, refinándolo a nivel de cada descendiente con datos y métodos llamados desde el nivel abstracto. En este contexto, la abstracción abre nuevos horizontes para la recursividad.
Características históricas de OOP
OOP ha llegado dos veces al mundo del software, aunque algunos expertos pueden señalar el surgimiento de la computación en la nube y las ideas modernas sobre objetos y clases como una nueva ronda en el desarrollo de tecnologías de TI.
Los términos "objeto" y "objetivo" en el contexto moderno de la programación orientada a objetos generalmente se atribuyen a los años 50 y 60 del siglo pasado, pero están asociados con 1965 y la aparición de Simula, Lisp, Algol, Smalltalk.
En aquellos días, la programación no estaba particularmente desarrollada y no podía responder adecuadamente a los conceptos revolucionarios. La lucha de ideas y estilos de programación (C / C ++ y Pascal, en su mayoría) aún estaba lejos, y las bases de datos aún estaban conceptualmente formadas.
A finales de los 80 y principios de los 90, aparecieron objetos en Pascal y todos recordaron las clases en C / C ++; esto marcó una nueva ronda de interés en OOP y fue entonces cuando las herramientas, principalmente los lenguajes de programación, dejaron de ser solo admite ideas orientadas a objetos, pero evoluciona en consecuencia.
Por supuesto, si los algoritmos recursivos anteriores eran solo funciones utilizadas en el código general del programa, ahora la recursividad podría convertirse en parte de las propiedades de un objeto (clase), lo que brindaría oportunidades interesantes en el contexto de la herencia.
Característica de programación orientada a objetos moderna
El desarrollo de OOP inicialmente declaró objetos (clases) como colecciones de datos y propiedades (métodos). De hecho, se trataba de datos que tienen sintaxis y significado. Pero entonces no fue posible presentar la programación orientada a objetos como una herramienta para gestionar objetos reales.
OOP se ha convertido en una herramienta para administrar objetos de "naturaleza informática". Un script, un botón, un elemento de menú, una barra de menú, una etiqueta en una ventana del navegador es un objeto. Pero no una máquina, un producto alimenticio, una palabra o una oración. Los objetos reales han permanecido fuera de la programación orientada a objetos y las herramientas informáticas han adquirido una nueva encarnación.
Debido a las diferencias en los lenguajes de programación populares, han surgido muchos dialectos de programación orientada a objetos. En cuanto a la semántica, son prácticamente equivalentes, y su enfoque en el ámbito instrumental, y no en el aplicado, permite llevar la descripción de objetos reales más alláalgoritmos y garantizar su "existencia" multiplataforma y multilenguaje.
Pilas y mecanismos de llamada de función
Los mecanismos para llamar funciones (procedimientos, algoritmos) requieren pasar datos (parámetros), devolver un resultado y recordar la dirección del operador que debe recibir el control después de que se completa la función (procedimiento).
Por lo general, la pila se usa para este propósito, aunque los lenguajes de programación o el propio desarrollador pueden proporcionar una variedad de opciones para transferir el control. La programación moderna admite que el nombre de una función puede ser no solo un parámetro: puede formarse durante la ejecución del algoritmo. También se puede crear un algoritmo mientras se ejecuta otro algoritmo.
El concepto de algoritmos recursivos, cuando sus nombres y cuerpos pueden determinarse en el momento de la formación de la tarea (elegir el algoritmo deseado), extiende la recursividad no solo a cómo hacer algo, sino también a quién debe hacerlo exactamente hazlo. Elegir un algoritmo por su nombre "significativo" es prometedor, pero crea dificultades.
Recursividad en un conjunto de funciones
No se puede decir que un algoritmo es recursivo cuando se llama a sí mismo y ya está. La programación no es un dogma, y el concepto de recursividad no es un requisito exclusivo para llamarse a sí mismo desde el cuerpo de su propio algoritmo.
Las aplicaciones prácticas no siempre dan una solución limpia. A menudo, los datos iniciales deben prepararse y el resultado de la llamada recursiva debe analizarse en el contexto de todo el problema (todo el algoritmo) entotal.
De hecho, no solo antes de que se llame a una función recursiva, sino también después de que se haya completado, se puede o se debe llamar a otro programa. Si no hay problemas especiales con la llamada: la función recursiva A() llama a la función B(), que hace algo y llama a A(), inmediatamente hay un problema con la devolución del control. Habiendo completado la llamada recursiva, la función A() debe recibir el control para volver a llamar a B(), que la llamará nuevamente. Devolver el control como debería estar en orden en la pila a B() es la solución incorrecta.
El programador no está limitado en la elección de parámetros y puede completarlos con nombres de funciones. En otras palabras, la solución ideal es pasar el nombre de B() a A() y dejar que A() llame a B(). En este caso, no habrá problemas para devolver el control y la implementación del algoritmo recursivo será más transparente.
Comprensión y nivel de recursividad
El problema con el desarrollo de algoritmos recursivos es que necesita comprender la dinámica del proceso. Cuando se usa la recursividad en métodos de objetos, especialmente al nivel de un ancestro abstracto, existe el problema de comprender su propio algoritmo en el contexto de su tiempo de ejecución.
Actualmente, no hay restricciones en el nivel de anidamiento de funciones y capacidad de pila en los mecanismos de llamada, pero hay un problema de comprensión: en qué momento, qué nivel de datos o qué lugar en el algoritmo general llamado recursivo función y en qué número de llamadas ella misma está.
Las herramientas de depuración existentes suelen ser impotentesdile al programador la solución correcta.
Bucles y recursividad
Se considera que la ejecución cíclica es equivalente a la recursividad. De hecho, en algunos casos, el algoritmo recursivo se puede implementar en la sintaxis de construcciones condicionales y cíclicas.
Sin embargo, si se entiende claramente que una función en particular debe implementarse a través de un algoritmo recursivo, se debe abandonar cualquier uso externo de un bucle o sentencias condicionales.
El significado aquí es que una solución recursiva en la forma de una función que se usa a sí misma será un algoritmo completo y funcionalmente completo. Este algoritmo requerirá que el programador lo cree con esfuerzo, entendiendo la dinámica del algoritmo, pero será la solución final que no requiere control externo.
Cualquier combinación de operadores condicionales y cíclicos externos no nos permitirá representar el algoritmo recursivo como una función completa.
Consenso de recursividad y programación orientada a objetos
En casi todas las variantes de desarrollo de un algoritmo recursivo, surge un plan para desarrollar dos algoritmos. El primer algoritmo genera una lista de objetos futuros (instancias) y el segundo algoritmo es en realidad una función recursiva.
La mejor solución sería organizar la recursividad como una sola propiedad (método) que realmente contiene el algoritmo recursivo, y poner todo el trabajo preparatorio en el constructor de objetos.
Un algoritmo recursivo solo será la solución correcta cuando funcionesolo por sí mismo, sin control y gestión externos. Un algoritmo externo solo puede dar una señal para que funcione. El resultado de este trabajo debería ser la solución esperada, sin apoyo externo.
La recursividad siempre debe ser una solución completa e independiente.
Comprensión intuitiva y funcionalidad completa
Cuando la programación orientada a objetos se convirtió en el estándar de facto, se hizo evidente que para codificar de manera eficaz, es necesario cambiar su forma de pensar. El programador debe pasar de la sintaxis y la semántica del lenguaje a la dinámica de la semántica durante la ejecución del algoritmo.
Característica de la recursividad: se puede aplicar a todo:
- raspado web;
- operaciones de búsqueda;
- análisis de información de texto;
- leer o crear documentos de MS Word;
- muestreo o análisis de etiquetas…
Característica de OOP: permite describir un algoritmo recursivo al nivel de un ancestro abstracto, pero permite que se refiera a descendientes únicos, cada uno de los cuales tiene su propia paleta de datos y propiedades.
La recursividad es ideal porque requiere la integridad funcional de su algoritmo. OOP mejora el rendimiento de un algoritmo recursivo dándole acceso a todos los hijos únicos.