Які алгоритми / структури даних я повинен “розпізнати” та знати по імені? [зачинено]


69

Я хотів би вважати себе досить досвідченим програмістом. Я займаюся програмуванням вже більше 5 років. Моє слабке місце, хоча термінологія. Я самоучка, тому, хоча я вмію програмувати, я не знаю деяких формальних аспектів інформатики. Отже, що таке практичні алгоритми / структури даних, які я міг би розпізнати та знати по імені?

Зауважте, я не прошу книжкової рекомендації щодо реалізації алгоритмів. Мені не важливо їх реалізовувати, я просто хочу мати можливість розпізнати, коли алгоритм / структура даних буде хорошим рішенням проблеми. Я прошу більше про список алгоритмів / структур даних, які я повинен "розпізнати". Наприклад, я знаю рішення такої проблеми:

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

Рішенням буде черга чи стек.

Я шукаю такі речі, як "в якій ситуації слід використовувати B-Дерево - Який алгоритм пошуку слід використовувати тут" і т. Д. І, можливо, швидке ознайомлення з тим, як складніші (але зазвичай використовувані) структури даних / алгоритми працюють.

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


10
Голосування про закриття як "неконструктивне". Будь-яка відповідь буде цілком суб’єктивною - немає єдиної думки щодо того, що слід знати ".
Одід

2
Яка частина цієї проблеми шафки потребує впорядкування вводу / виводу? [натяк!]
Теластин

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

6
@Oded Немає консенсусу? Що щодо програми вступного курсу з алгоритмів та структур даних з інформатики? Досить добре стандартизований та рецензований . Хороший вихідний пункт.
MarkJ

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

Відповіді:


78

Об'єктивна відповідь:

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

Однак, я все ще думаю, що мій список досить гарний.

Оригінальна відповідь нижче.


Що я повинен знати?

Мінімум

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

Щоб відповісти на головне запитання, ось що повинен знати студент бакалаврату (фундамент адекватного програміста) після закінчення навчання:

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

  • Машинне представлення даних
    • Одні, доповнення двох та пов'язана з ними арифметика
    • Слова, покажчики, плаваюча точка
    • Бітовий доступ, зсув та маніпуляція
  • Пов'язані списки
  • Хеш-таблиці (карти чи словники)
  • Масиви
  • Дерева
  • Стеки
  • Черги
  • Графіки
  • Бази даних

Алгоритми

  • Сортування:
    • Сортування бульбашок (щоб знати, чому це погано)
    • Сортування вставки
    • Об’єднати сортування
    • Швидкий сортування
    • Сорти в стилі Radix, підрахунок сортування та сортування відра
    • Сортування купи
    • Бого і квантовий сортування (=
  • Пошук:
    • Лінійний пошук
    • Двійковий пошук
    • Перший пошук по глибині
    • Перший пошук ширини
  • Рядок маніпуляції
  • Ітерація
  • Обхід дерева
  • Перехід списку
  • Функції хешування
  • Конкретна реалізація таблиці хешу, дерева, списку, стека, черги, масиву та набору або колекції
  • Алгоритми планування
  • Обхід файлової системи та маніпуляція (на рівні inode або еквівалент).

Шаблони дизайну

  • Модуляризація
  • Заводська
  • Будівельник
  • Сінглтон
  • Перехідник
  • Декоратор
  • Легкий вага
  • Спостерігач
  • Ітератор
  • Штат [машина]
  • Контролер перегляду моделі
  • Шаблони програмування ниток та паралельних програм

Парадигми

  • Імператив
  • Об'єктно-орієнтована
  • Функціональний
  • Декларативний
  • Статичне та динамічне програмування
  • Розмітка даних

Теорія складності

  • Простори простору
  • Обчислюваність
  • Регулярні, безтекстові та універсальні машини Тьюрінга на повному мовах
  • Регулярні вирази
  • Підрахунок та основна комбінаторика

Поза

Щоб дізнатися про те, про що ви питаєте, пізніше у вашому запитанні, якщо ви знайомі з вищесказаним, вам слід легко визначити відповідну схему, алгоритм та структуру даних для заданого сценарію. Однак слід визнати, що найкращого рішення часто не існує. Іноді від вас може знадобитися вибрати менше двох злом або навіть просто вибрати між двома однаково життєздатними рішеннями. Через це вам потрібні загальні знання, щоб мати можливість відстояти свій вибір від своїх однолітків.

Ось кілька порад щодо алгоритмів та структур даних:

  • Бінарний пошук можна використовувати (і повинен) використовувати лише для відсортованих даних.
  • Сорти в стилі Radix є приголомшливими, але лише тоді, коли у вас є сортовані обмежені класи.
  • Дерева корисні майже для всього, як і столу хешу. Функціонал таблиці Hash можна екстраполювати і використовувати для вирішення багатьох проблем ціною ефективності.
  • Масиви можна використовувати для резервування більшості структур даних більш високого рівня. Іноді "структура даних" - це не більше ніж якась розумна математика для доступу до місць у масиві.
  • Вибір мови може бути різницею між витягуванням волосся або пропливом через проблему.
  • Таблиця ASCII та масив 128 елементів утворюють неявну хеш-таблицю (=
  • Регулярні вирази можуть вирішити багато проблем, але їх не можна використовувати для розбору HTML .
  • Іноді структура даних так само важлива, як алгоритм.

Деякі з перерахованих вище можуть здатися відсутніми, а деякі можуть здаватися невиразними. Якщо ви хочете, щоб я детальніше пішов, я можу. Але, я сподіваюсь, що зіткнувшись з більш конкретним питанням, таким як "Створити функцію, яка враховує кількість зустрічей кожного символу в рядку", ви подивитесь на підказку щодо таблиці ASCII та масивів 128 елементів, що утворюють акуратний неявний хеш таблиці для відповіді.

Виходячи з цих ідей, я запропоную відповідь на проблему шафки, викладену у вашому запитанні.


Відповідь на проблему, поставлену у вашому запитанні.

Це може бути не найкращою відповіддю на ваше запитання, але я думаю, що це цікавий, що не вимагає нічого занадто складного. І це, безумовно, обіграє складність у часі використання черги, або стека, який вимагає лінійного часу, щоб визначити, вільний шафка чи ні.

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

Це рішення працює в постійному часі для пошуку та зберігання, на відміну від зберігання та пошуку журналу (n) часу у випадку черги пріоритету, підтримуваної двійковим деревом. Опис навмисно багатослівний, так що ви можете бачити вищі поняття, зведені в ефективний алгоритм.

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


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

1
Відмінно! Особливо "Регулярні вирази можуть вирішити багато проблем, але їх не можна використовувати для розбору HTML".
FrustratedWithFormsDesigner

2
Відповідь була хорошою, поки не з’явилася «проблема». Немає жодної причини використовувати чергу пріоритету чи хеш-таблицю. Досить простого стека. Додайте ітерацію, щоб отримати повний список безкоштовних шаф, якщо бажаєте.
Матьє М.

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

1
Я скептично ставлюсь до шаблонів дизайну. Багато хто корисний на деяких мовах, а в інших - непотрібних та / або непотрібних. Ви також можете додати евристику під алгоритми та структури даних трие та пропускного списку. Традиційні алгоритми / структури даних досягають обмеження щодо синхронного доступу, але можуть бути переможені іншими нетрадиційними підходами з використанням декількох потоків та одночасності. Евристика може різко зменшити кількість потрібних пошукових запитів, тоді як структури, такі як пропускний список, дозволять записувати структуру даних без глобального блокування.
Еван Плейс

6

Посібник з дизайну алгоритму Стівена С. Скіени здається джерелом, яке ви шукаєте. Друга частина - це класифікований перелік проблем із оглядом відповідних алгоритмів. Є веб-версія .


3
чудова книга, але не відчуваю, що вам доведеться все це опанувати, щоб справді бути програмістом. Нещодавно я його придбав, а програму мені платять з 1979 року. (І так, я купив її, вважаючи, що я можу щось навчитися.)
Кейт Грегорі

@KateGregory Я купив книгу і не міг реально розвісити її, бо знаю лише мови високого рівня, такі як Ruby та Javascript (відсутність бінарних дерев, пов'язані списки тощо) ... Я врешті відмовився від її читання.
bigpotato

4

Немає "слід". A. Ознайомтеся з основними класами складності (лінійними, логарифмічними тощо). B. Зрозумійте, що ви можете робити майже все, що є простим масивом, як ви можете з фантазійною структурою даних, як B-дерево. Трюк у виборі відповідної структури / алгоритму полягає в балансуванні продуктивності, очікуваному розмірі введення та складності реалізації.

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


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

3

MIT публікує безкоштовні конспекти лекцій, відеоролики, завдання та екзаменаційні матеріали для вступу до алгоритмів . У заголовках лекцій перераховані охоплені алгоритми / структури даних.

Це рецензований консенсус щодо того, що слід знати. Це, мабуть, і чудовий навчальний ресурс.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.