Изучение эффективных алгоритмов - PullRequest
15 голосов
/ 12 марта 2011

До сих пор я в основном концентрировался на том, как правильно спроектировать код, сделать его максимально читабельным и обслуживаемым, насколько это возможно. Поэтому я всегда хотел узнать о деталях более высокого уровня программирования, таких как взаимодействие классов, дизайн API и т. Д.

Алгоритмы, которые я никогда не находил особенно интересными. В результате, даже несмотря на то, что я могу придумать хороший дизайн для своих программ, и даже если я могу найти решение для определенной проблемы, это редко является наиболее эффективным.

Существует ли какой-то особый способ думать о проблемах, который помогает вам найти максимально эффективное решение, или это просто вопрос практики и / или запоминания?

Кроме того, какие онлайн-ресурсы вы можете порекомендовать, чтобы научить вас различным эффективным алгоритмам для решения различных задач?

Ответы [ 5 ]

12 голосов
/ 12 марта 2011

Данные доминируют . Если вы разрабатываете свою программу на основе правильных абстрактных структур данных (ADT), вы часто получаете чистый дизайн, алгоритмы следуют совершенно естественным образом, а при недостаточной производительности вы сможете подключить более эффективные.

В этом помогает сильный фон в математике и логике, поскольку он позволяет визуализировать вашу программу на высоком уровне в виде взаимодействия между функциями, наборами, графиками, последовательностями и т. Д. Затем вы решаете, нужно ли упорядочивать наборы ( сбалансированные BST, операции O (lg n)) или нет (хеш-таблицы, операции O (1)), какие операции необходимо поддерживать для последовательностей (векторно-подобные или спискообразные) и т. д.

Если вы хотите изучить некоторые алгоритмы, найдите хорошую книгу, такую ​​как Cormen et al. и попробуйте реализовать основные структуры данных:

  • деревья бинарного поиска
  • универсальные бинарные деревья поиска (которые работают не только с int или строками)
  • хеш-таблицы
  • приоритетные очереди / кучи
  • динамические массивы
7 голосов
/ 12 марта 2011

Введение в алгоритмы - отличная книга, которая поможет вам задуматься об эффективности различных алгоритмов / структур данных.

Авторы книги также проводят курс по алгоритмам MIT. Вы можете найти большинство лекций здесь

3 голосов
/ 12 марта 2011

Я бы сказал, что, придумывая хорошие алгоритмы (что на самом деле является частью хорошего дизайна ИМХО), вы должны выработать способ мышления.Лучше всего это сделать, изучив алгоритм проектирования.Под изучением я имею в виду не просто знание всех общих алгоритмов, описанных в учебнике, но на самом деле понимание того, как и почему они работают, и способность применять основную идею, содержащуюся в них, к реальным проблемам, которые вы пытаетесь решить.

Я бы предложил почитать хорошую книгу по алгоритмам (мой любимый - CLRS).Для онлайн-ресурса я бы порекомендовал серию статей в Учебниках по алгоритму TopCoder .

. Я не понимаю, почему вы упоминаете практику и заучивание на одном дыхании.Запоминание вам совсем не поможет (вы, наверное, уже знаете это), но практика необходима.Если вы не можете применить то, что вы узнали, это не совсем обучение.Вы можете попрактиковаться в различных онлайн-конкурсах / головоломках, таких как SPOJ , Project Euler и PythonChallenge .

1 голос
/ 12 марта 2011

Рекомендации: Прежде всего, я рекомендую книгу «Введение в алгоритмы, второе издание Кормана», в отличной книге есть большинство (если не все) алгоритмов, которые вам понадобятся. (Некоторые из наиболее важных тем - алгоритмы сортировки, кратчайшие пути, динамическое программирование, многие структуры данных, такие как bst, карты хешей, кучи).

еще один отличный способ выучить алгоритмы - это http://ace.delos.com/usacogate, отличная практика после начала.

К вашим вопросам вы просто привыкнете писать хороший быстро работающий код, после небольшой практики вам просто не захочется писать неэффективный код.

0 голосов
/ 13 марта 2011

Хотя я думаю, что @larsmans является правильным, поскольку понимание логики и математики - это быстрый способ понять, как выбрать полезные ADT для решения данной проблемы, изучение существующих решений может быть более поучительным для тех из нас, кто борется с этими темами. В частности, обзор кода установленного программного обеспечения (OSS), который решает проблему, аналогичную той, которая вас интересует.

Я считаю, что особенно хорошим методом для этого метода изучения является проверка юнит-тестов такого проекта. Apache Lucene , например, имеет репозиторий управления исходным кодом, содержащий множество примеров. Хотя он не раскрывает основные алгоритмы, он помогает проследить конкретную функциональность, которая решает определенную проблему. Это приводит к возможности изучения его внутренних особенностей - то есть интересного алгоритма. В случае Lucene на ум приходят перевернутые индексы .

Хотя это не гарантирует, что алгоритм, который вы обнаружите, является наилучшим, он, вероятно, подвергся тщательному анализу и, вероятно, поступил из проекта с активной рассылкой, которая может ответить на ваши вопросы. Так что это хороший ресурс для поиска решения, которое, вероятно, лучше, чем то, что большинство из нас придумали бы самостоятельно.

...