Soy un desarrollador de fuerza bruta, ¿cómo puedo mejorar mis habilidades de algoritmos?

En general, los programadores principiantes (novatos) llegan a una solución que es un enfoque de fuerza bruta. Lo cual no está mal para empezar. Todo lo que tiene que hacer es pensar dónde puede reducir la complejidad.

Esto es lo que te sugiero que hagas:

Anote su solución:

Hágalo en una pizarra grande o en papel, analice el componente clave de su programa, su solución debería poder traducirse en uno o varios métodos individuales. Tener componentes separados para diferentes soluciones no está nada mal. Asegúrese de que su algoritmo clave esté en uno de los métodos solamente.

Analiza tu solución:

Esta es una de las partes más difíciles, descubra la complejidad de su solución. Si no está seguro de cómo averiguar la complejidad de la solución, le sugiero que lea los capítulos 2, 3 y 4 (este es para darle una mejor idea sobre el análisis de complejidad) de Introducción al algoritmo de CLRS.

Encontrar los puntos de dolor:

Puede reducir la complejidad de la mayoría de los problemas (a veces) clasificando el conjunto de datos. Recuerde que no va a reducir su carga de trabajo por mucho, pero definitivamente reducirá el tiempo cuadrático a [matemáticas] O (n \ log n) [/ matemáticas] en algunos casos, lo cual es mucho mejor que eso.

Trabajar en un conjunto de datos ordenado es la mayoría de las veces mejor que trabajar en un conjunto de datos no ordenado. La clasificación hace que la búsqueda en un conjunto de datos determinado sea muy fácil.

Recuerde que la clasificación no siempre es una solución:

Es común entre las personas clasificar los elementos, pero recuerde que no siempre le ayudará si se supone que debe encontrar [math] m [/ math] elementos más grandes de la lista no clasificada de [math] n [/ math] de elementos, puede usar el algoritmo de selección (algoritmo de selección – Wikipedia). El peor de los casos para este algoritmo es [matemática] n [/ matemática].

Reduzca el número de bucles secuenciales:

Reduzca el número de bucles secuenciales, al final no importa tanto, pero es solo una mejora de micro nivel en su programa.

Reduzca el número de bucles anidados:

Intente averiguar los lugares donde puede eliminar el bucle anidado, a veces un bucle dentro de un bucle parece anidado pero se ejecuta n veces.

Utilice bibliotecas incorporadas para la operación conocida:

No intente reinventar la rueda, la mayoría de los lenguajes de programación le brindan una amplia cantidad de herramientas que lo ayudarán a resolver la clasificación, la búsqueda, etc.

Los hashmaps no son la solución a todos los problemas:

La mayoría de las personas que conozco tienden a usar mucho Hashmaps. Recuerde siempre que puede resolver muchos problemas, pero también ocupa una gran cantidad de espacio. Si puede resolver problemas usando listas o matrices, simplemente hágalo.

CLRS es útil:

Le recomiendo que vaya con las declaraciones de problemas de CLRS, que lo ayudan mucho a comprender problemas similares que podría enfrentar al resolver un problema y el enfoque de la mayoría de ellos le da una idea clara de un problema similar. El manual de diseño de algoritmos de Steven Skiena también es bueno.

Práctica:

Cuantos más problemas practiques, más ganarás.

Los algoritmos son, de hecho, una habilidad importante. Su habilidad de algoritmo mejora simplemente al saber qué algoritmos existen y para qué sirven. No necesita tener todas sus implementaciones memorizadas. Solo saber lo que es posible y tener una idea de los problemas que ya se han resuelto, le dará una pista sobre cuándo debe desenterrar una implementación de algoritmo.

Otras respuestas mencionan formas específicas de aprender algoritmos. Otras preguntas tienen buenas listas de algoritmos para aprender. [1] También es importante hacer un perfil para descubrir a dónde va el tiempo en su código.

Pero hay dos puntos importantes que están subrepresentados en las respuestas:

  • Si usa un lenguaje de alto nivel, suceden muchas cosas que no puede ver. Puede obtener una comprensión intuitiva de lo que está sucediendo detrás de la cortina, lo que lo ayudará a escribir un código de hábito más óptimo. Una forma de obtener esta información es aprender un lenguaje de nivel inferior (al menos C, pero idealmente lenguaje ensamblador). Un experto en CS normalmente obtendrá esto en una clase de diseño de compilador. El Libro del Dragón [2] es una buena referencia. Vea si puede encontrarlo en una biblioteca.
  • Si usa un lenguaje lento , el mejor algoritmo posible por sí solo no hará que su código sea tan escalable como cambiar a un idioma mejor. La mejora de la velocidad de usar un mejor algoritmo depende de su “n” (la cantidad de datos que está procesando). El uso de un mejor idioma puede brindarle una mejora de 20 [3] – 1000x [4] en el rendimiento del servidor. Con una n alta, esta ganancia podría estar por encima de un aumento del rendimiento del lenguaje.

¡Buena suerte!

Notas al pie

[1] ¿Cuáles son los 10 algoritmos que cada estudiante de informática debe implementar al menos una vez en la vida?

[2] Compiladores: principios, técnicas y herramientas – Wikipedia

[3] Puntos de referencia del marco TechEmpower

[4] Puntos de referencia del marco TechEmpower

En primer lugar, felicidades por tratar de aprender cómo escribir un código mejor. Verás que el tiempo y el esfuerzo que pones serán ampliamente recompensados. No solo su código puede ejecutarse de manera más eficiente, sino que probablemente le ahorrará tiempo al escribir, depurar y mantener su código.

Si está interesado en algoritmos, puedo recomendar un libro que es clásico en informática:

Introducción a los algoritmos de Thomas H. Comen, Charles E. Leiserson Ronald L. Rivest y Clifford Stein

Es un libro bastante pesado (más de 1200 páginas). Quizás sea suficiente verificar los primeros tres capítulos (Fundamentos de las estructuras de datos) al principio.

Esto podría ayudarlo a ver las cosas desde un nivel superior y también descubrir algunos de los trucos increíblemente inteligentes que se usan comúnmente en este mundo.

Sin embargo, si su interés principal es aumentar la velocidad, le animo a que investigue los detalles de su lenguaje de programación favorito. Por ejemplo, cómo se implementan la matriz y las matrices, o las API disponibles para estructuras de datos específicas (pilas, montones, mapas, etc.)

Lo que funciona para un lenguaje de programación podría no funcionar para el otro.

Espero que esto ayude.

He leído sobre la notación Big-O, los algoritmos de búsqueda, clasificación y hash. Antes de escribir el código en un editor directamente, primero escribo un pseudocódigo en un papel y trato de encontrar su complejidad de tiempo (usando la notación Big-O).
Una vez que conozco la complejidad del tiempo, trato de optimizarla utilizando los conceptos que ya conozco. Pienso en todas las técnicas que puedo aplicar para reducir la complejidad temporal de mi código. Uno puede darse cuenta fácilmente de esto si comprende bien algunos algoritmos estándar. Le sugiero que comience desde la notación Big-O y luego aprenda algunos algoritmos básicos (mencionados anteriormente).

No diré que no aprendas algoritmos: si crees que serán útiles, entonces, sumérgete en aprenderlos. Consulte las otras respuestas para obtener ideas sobre cómo hacer esto.

Personalmente, no me gusta especialmente el diseño a nivel de código. Si voy a entrar en tantos detalles, bien podría escribirlo como código real. De esa manera, puedo probarlo en lugar de tratar de adivinar cuáles podrían ser los posibles problemas. Sin embargo, puede ser un ejercicio que valga la pena, como han señalado otras personas. Este es uno de esos, su millaje puede variar en casos.

Si tiene un código de trabajo que no funciona bien, entonces puede ser el momento de crear un generador de perfiles. Vale la pena hacerlo antes de intentar adivinar dónde pueden estar los problemas. Puede que tengas razón, y hay una serie de buenas sugerencias para probar en otra respuesta, pero es posible que no veas el problema real. Aunque la creación de perfiles a veces puede ser difícil hacer lo correcto, puede ser una herramienta valiosa para localizar un problema. Si los usa correctamente, puede encontrar problemas de CPU y memoria.

Intente escribir los pasos que desea lograr en un documento.Si mantiene el mismo enfoque de fuerza bruta incluso con esos pasos, escriba todo el algoritmo en papel y solo pruebe en la PC cuando realmente crea que funcionará.

leetcode

carrera profesional

etc.

Intente escribir respuestas a las preguntas en esos sitios y compare su solución (si puede encontrar una) con otras en línea.

More Interesting

Un profesor me dijo que no me molestara en aprender muchos lenguajes de programación sino que me enfocara solo en C ++, estructuras de datos y algoritmos, ¿tiene razón?

Dado un volumen que consiste en un número de ubicaciones dentro de un espacio tridimensional definido, y a cada una de estas ubicaciones se le asigna algún número, ¿hay alguna métrica obvia que se pueda aplicar que mida la complejidad de la distribución de las mediciones?

Dos jugadores juegan el siguiente juego: hay N piedras en la mesa, el jugador puede tomar 1 o 2 piedras (si N mod 3 = 0), 1 o 3 (si N mod 3 = 1) y 1, 2 o 3 ( si N mod 3 = 2). ¿Cómo determino al ganador en el juego?

¿Con qué tipo de algoritmo debo comenzar desde el principio?

¿Qué es el algoritmo de transformación de Burrows-Wheeler y cómo se usa en aplicaciones del mundo real?

Cómo eliminar caracteres duplicados en la cadena char * p = 'chaabbcc'

¿Cuál es la diferencia entre un algoritmo genético y un algoritmo de escalador?

¿Cuál es la diferencia entre tener un buen algoritmo y no tener uno?

Cómo usar el algoritmo profundo de Facebook en nuestra aplicación

¿Puedo hacer que un usuario de matriz ingrese su tamaño?

¿Cuál es la forma más eficiente de detectar, si una cadena es un anagrama de un palíndromo?

¿Cómo funciona el algoritmo iPod shuffle?

¿Qué es el código binario?

Cómo devolver una matriz multidimensional utilizando dos parámetros en C ++

¿Cuáles son los algoritmos necesarios para resolver un cubo de rubics?