Какие алгоритмы / структуры данных я должен «распознавать» и знать по имени? [закрыто]


69

Я хотел бы считать себя довольно опытным программистом. Я программирую уже более 5 лет. Мое слабое место, хотя это терминология. Я самоучка, поэтому, хотя я знаю, как программировать, я не знаю некоторые из более формальных аспектов информатики. Итак, что такое практические алгоритмы / структуры данных, которые я мог бы узнать и узнать по имени?

Обратите внимание, я не прошу рекомендации книги по реализации алгоритмов. Меня не волнует их реализация, я просто хочу уметь распознавать, когда алгоритм / структура данных будет хорошим решением проблемы. Я прошу больше список алгоритмов / структур данных, которые я должен «распознать». Например, я знаю решение такой проблемы:

Вы управляете набором шкафчиков с надписью 0-999. Люди приходят к вам, чтобы арендовать шкафчик, а затем возвращаются, чтобы вернуть ключ от шкафчика. Как бы вы создали программное обеспечение для управления, зная, какие шкафчики бесплатны, а какие используются?

Решением будет очередь или стек.

Я ищу такие вещи, как «в какой ситуации следует использовать B-Tree - какой алгоритм поиска следует использовать здесь» и т. Д. И, возможно, быстрое представление о том, как более сложные (но обычно используемые) структуры данных / алгоритмы работают.

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


10
Голосование закрывать как «не конструктивно». Любой ответ будет полностью субъективным - нет единого мнения о том, что «следует» знать.
передано

2
Какая часть этой проблемы с локером требует упорядочения ввода / вывода? [подсказка!]
Теластин

5
@ Oded есть список, который, я думаю, большинство людей согласятся, для каких структур данных и алгоритмов должен знать опытный программист.
Дэвид Коуден

6
@Oded Нет единого мнения? Как насчет учебного курса по алгоритмам и структурам данных в информатике? Довольно хорошо стандартизирован и рецензирован . Хорошая отправная точка.
MarkJ

3
Альтернативное решение; Предположим, вы заряжаете в течение дня и имеете максимальный заряд. Прикрепите бумажный ярлык к ключу, когда вы включите шкафчик, и напишите на нем номер юлианского дня. Когда ключ будет возвращен, посмотрите на тег, чтобы рассчитать арендную плату. Отсутствующие или испорченные метки привлекают максимальный заряд. Неиспользуемые ключи хранятся в сумке (поскольку нет необходимости выбирать какой-либо конкретный ключ из свободных ключей при сдаче шкафчика). Общий размер структуры данных: ноль битов. Все части алгоритма O (1).
Джеймс Янгман

Ответы:


78

Объективный ответ:

В то время как мой первоначальный ответ на этот вопрос был основан на моем эмпирическом опыте студента CS, готовящегося к поступлению в аспирантуру, и моем прогнозируемом мнении о типе людей, с которыми я хотел работать в области CS. На самом деле существует объективный (в отношении субъективных мнений компьютерных сообществ ACM SIGCSE и IEEE) ответ. Каждые 10 лет органы ACM и IEEE сотрудничают в совместной публикации, в которой подробно излагаются предложения по учебной программе по компьютерным наукам для студентов на основе профессиональных знаний о состоянии компьютерной индустрии. Более подробную информацию можно найти на cs2013.org . Комитет публикует итоговый отчет, в котором перечисляются рекомендации по учебной программе .

Тем не менее, я все еще думаю, что мой список довольно хорош.

Оригинальный ответ ниже.


Что я должна знать?

минимальный

Я думаю, что опытный программист должен иметь как минимум знания бакалавриата в области компьютерных наук. Несомненно, вы можете быть эффективными на многих работах, имея лишь небольшое подмножество компьютерных наук, потому что сообщество CS, основанное на твердой репутации, и суженный фокус большинства профессиональных должностей. Кроме того, многие люди будут специализироваться после окончания бакалавриата. Тем не менее, я не думаю, что это оправдание того, что мы не знакомы с фундаментальными знаниями CS.

Чтобы ответить на заглавный вопрос, вот, что студент бакалавриата CS (основа для программиста-адепта) должен знать после окончания обучения:

Структуры данных

  • Представление машинных данных
    • Единицы, дополнение к двум и связанная с ними арифметика
    • Слова, Указатели, Плавающая Точка
    • Битовый доступ, смещение и манипулирование
  • Связанные списки
  • Хеш-таблицы (карты или словари)
  • Массивы
  • деревья
  • Стеки
  • Очереди
  • диаграммы
  • Базы данных

Алгоритмы

  • Сортировка:
    • Bubble Sort (чтобы понять, почему это плохо)
    • Сортировка вставки
    • Сортировка слиянием
    • Быстрая сортировка
    • Сортировка в стиле Radix, сортировка по счетам и сортировка по ведрам
    • Куча сортировка
    • Bogo и Quantum Sort (=
  • Поиск:
    • Линейный поиск
    • Бинарный поиск
    • Глубина Первый Поиск
    • Ширина Первый Поиск
  • Манипуляция строк
  • итерация
  • Обход дерева
  • Обход списка
  • Хеширующие функции
  • Конкретная реализация хеш-таблицы, дерева, списка, стека, очереди, массива и набора или коллекции
  • Алгоритмы планирования
  • Обход и манипулирование файловой системой (на уровне inode или эквивалентном уровне).

Шаблоны проектирования

  • Модульность
  • завод
  • строитель
  • одиночка
  • адаптер
  • декоратор
  • легкий вес
  • наблюдатель
  • Итератор
  • Государственный аппарат]
  • Контроллер модельного вида
  • Потоки и шаблоны параллельного программирования

парадигмы

  • Императив
  • Объектно-ориентированный
  • функциональная
  • декларативный
  • Статическое и Динамическое Программирование
  • Разметка данных

Теория сложности

  • Сложность Пространств
  • Computability
  • Обычные, контекстно-свободные и универсальные машины Тьюринга завершают языки
  • Обычные выражения
  • Подсчет и базовая комбинаторика

за

Чтобы разобраться в том, о чем вы спрашиваете позже в своем вопросе, если вы знакомы с вышеизложенным, вы сможете легко определить подходящий шаблон, алгоритм и структуру данных для данного сценария. Однако вы должны признать, что зачастую не существует лучшего решения. Иногда вам может потребоваться выбрать меньшее из двух зол или даже просто выбрать между двумя одинаково жизнеспособными решениями. Из-за этого вам нужны общие знания, чтобы защитить свой выбор от своих сверстников.

Вот несколько советов для алгоритмов и структур данных:

  • Бинарный поиск может (и должен) использоваться только для отсортированных данных.
  • Сортировка в стиле Radix - это круто, но только когда у вас есть сортировка по конечным классам.
  • Деревья хороши для чего угодно, как и Хеш-таблицы. Функциональность хэш-таблицы может быть экстраполирована и использована для решения многих проблем за счет эффективности.
  • Массивы могут использоваться для поддержки большинства структур данных более высокого уровня. Иногда «структура данных» - это не более чем умная математика для доступа к местоположениям в массиве.
  • Выбор языка может быть разницей между тем, как выдернуть волосы или преодолеть проблему.
  • Таблица ASCII и массив из 128 элементов образуют неявную хеш-таблицу (=
  • Регулярные выражения могут решить много проблем, но их нельзя использовать для разбора HTML .
  • Иногда структура данных так же важна, как и алгоритм.

Некоторые из вышеперечисленных могут показаться легким делом, а некоторые могут показаться расплывчатыми. Если вы хотите, чтобы я углубился в детали, я могу. Но я надеюсь, что, столкнувшись с более конкретным вопросом, таким как «Разработка функции, которая подсчитывает количество вхождений каждого символа в строке», вы обращаетесь к совету о таблице ASCII и 128 массивах элементов, образующих аккуратный неявный хеш таблицы для ответа.

Основываясь на этих идеях, я предложу ответ на проблему с замком, изложенную в вашем вопросе.


Ответьте на проблему, поставленную в вашем вопросе.

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

У вас есть 0-999 шкафчиков. Теперь, поскольку у вас есть фиксированное количество шкафчиков, вы можете легко представить функцию хеширования без коллизий в диапазоне 0-999. Эта функция просто h (x) = x mod 1000. Теперь [концептуально] создайте хеш-таблицу с целочисленными ключами и содержимым массива char из 1000 элементов в качестве ваших значений. Если клиент хочет зарезервировать шкафчик 78 для использования, просто поместите 78 в хеш-функцию (возвращая 78), а затем добавьте это число к базовому указателю массива - сохраняя истинное значение в месте, указанном значением смещения , Точно так же, если вам нужно проверить, используется ли 78, просто прочитайте значение, хранящееся в этом месте, и проверьте значение true.

Это решение работает в постоянном времени для поиска и хранения, в отличие от хранения журнала (n) и поиска в случае очереди с приоритетами, поддерживаемой двоичным деревом. Описание намеренно многословно, поэтому вы можете увидеть, как высшие концепции сводятся к эффективному алгоритму.

Теперь вы можете спросить, а что если мне нужно знать все доступные шкафчики, не будет ли приоритетная очередь лучше? Если в очереди приоритетов имеется k доступных шкафчиков, итерация по всем из них займет k шагов. Кроме того, в зависимости от реализации приоритетной очереди вам может потребоваться перестроить приоритетную очередь при просмотре всего этого, что потребует k * log (k): (k <1000) шагов. В решении с массивами вам нужно всего лишь перебрать массив из 1000 элементов и проверить, какие из них открыты. Вы также можете добавить доступный или использованный список к реализации, чтобы проверить только за k раз.


1
Отличный ответ! Я также хотел бы добавить, что вы действительно должны быть уверены в использовании предопределенных функций / структур данных используемого вами языка, например, алгоритма и структур данных stl в C ++ или Java API для Java.
Марктани

1
Отлично! Особенно «Регулярные выражения могут решить множество проблем, но их нельзя использовать для разбора HTML».
FrustratedWithFormsDesigner

2
Ответ был хорош, пока не появилась «проблема». Нет никакой причины использовать очередь с приоритетами или хэш-таблицу. Простого стека достаточно. Добавьте итерацию, чтобы получить полный список бесплатных шкафчиков, если хотите.
Матье М.

1
должны ли мы добавить реляционную базу данных + SQL, знание дерева B +, теорию компилятора, организацию аппаратного обеспечения знаний, знание теории операционных систем, знание сетей TCP / IP?
dan_l

1
Я скептически отношусь к шаблонам дизайна. Многие из них полезны в некоторых типах языков, но бесполезны и / или не нужны в других. Возможно, вы также захотите добавить эвристику в алгоритмы, а также в структуры данных trie и skip-list. Традиционные алгоритмы / структуры данных достигают предела синхронного доступа, но могут быть побеждены другими нетрадиционными подходами, использующими несколько потоков и параллелизм. Эвристика может значительно уменьшить количество запросов на поиск, в то время как такие структуры, как список пропусков, позволят записывать структуру данных без глобальной блокировки.
Эван Плейс

6

Руководство по разработке алгоритмов Стивена С. Скиены кажется источником, который вы ищете. Вторая часть представляет собой секретный список проблем с обзором связанных алгоритмов. Есть веб-версия .


3
отличная книга, но не думайте, что вам нужно освоить все это, чтобы стать программистом. Я только что купил его недавно, и мне платят за программу с 1979 года. (И да, я купил его, полагая, что могу чему-то научиться.)
Кейт Грегори

@KateGregory Я купил книгу и не смог ее освоить, потому что я знаю только языки высокого уровня, такие как Ruby и Javascript (без двоичных деревьев, связанных списков и т. Д.) ... В конце концов я перестал читать.
bigpotato

4

Там нет "должен". A. Познакомьтесь с базовыми классами сложности (линейными, логарифмическими и т. Д.). Б. Поймите, что вы можете делать что угодно с простым массивом, как с сложной структурой данных, такой как B-дерево. Хитрость в выборе подходящей структуры / алгоритма заключается в балансировке производительности, ожидаемого размера ввода и сложности реализации.

Затем есть абстрактные, но чрезвычайно полезные вещи (хотя полезность не сразу очевидна): конечные автоматы, теория графов, теория выпуклости (линейное программирование и т. Д.).


1
Не стоит недооценивать важность знания того, когда что использовать. Потому что те проблемы, которые вы решили с помощью простого массива, будут возвращаться и кусать вас, когда вы собираетесь запустить этот большой клиент и выяснить, что ваше приложение, которое работало годами, замедляется до ползания только потому, что вы использовали пузырьковую сортировку вместо быстрая сортировка.
Питер Б

3

MIT публикует бесплатные лекционные заметки, видео, задания и экзаменационные материалы для введения в алгоритмы . В заголовках лекций перечислены алгоритмы / структуры данных.

Это рецензируемый консенсус о том, что вы должны знать. Это, вероятно, отличный учебный ресурс тоже.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.