Выбор языка программирования для изучения структур данных и алгоритмов [закрыто]

79

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

Учитывая следующее:

  • Личный опыт
  • Возможности языка (указатели, объектно ориентированный объект и т. Д.)
  • Пригодность для изучения концепций DS&A

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

Кроме того, есть другие книги, которые знакомят с концепциями DS & A с примерами, написанными на определенном языке программирования - и я хотел бы также закодировать эти алгоритмы - таким образом, в определенной степени язык также выбирает книгу.

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

Bguiz
источник
На этот вопрос нет другого способа ответить, кроме как конкретным, и для этого нужна дополнительная информация.
Дэвид Торнли
@ Дэвид Торнли: Я понимаю, что это немного открытый вопрос, но он получил много действительно отличных ответов!
bguiz
Много шума вызывает энергетическая (раньше: время) эффективность алгоритмов и структур данных: если и когда вы хотите это измерить, ищите системы, в которых значимые числа воспроизводимо (и легко) получаются.
greybeard

Ответы:

88

Ответ на этот вопрос зависит от того, что именно вы хотите узнать.

Python и Ruby

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

Кроме того, Ruby и Python - это языки с динамической типизацией. Это может быть хорошо, но также может сбивать с толку новичка, и может быть труднее (изначально) отловить ошибки, поскольку они обычно не проявляются до времени выполнения.

C

C - другая крайность. Это хорошо, если вы хотите изучить действительно низкоуровневые детали, такие как управление памятью, но управление памятью внезапно становится важным соображением, например, при правильном использовании malloc () / free (). Это может отвлекать. Кроме того, C не является объектно-ориентированным. Это неплохо, но стоит просто отметить.

C ++

Был упомянут C ++. Как я уже сказал в комментарии, я считаю, что это ужасный выбор. C ++ ужасающе сложен даже в простом использовании и имеет смехотворное количество "ошибок". Кроме того, C ++ не имеет общего базового класса. Это важно, потому что структуры данных, такие как хеш-таблицы, зависят от наличия общего базового класса. Вы можете реализовать версию для номинального базового класса, но это будет немного менее полезно.

Ява

Также упоминалась Java. Многим людям нравится ненавидеть Java, и это правда, что язык чрезвычайно многословен и лишен некоторых более современных языковых функций (например, закрытий), но на самом деле все это не имеет значения. Java статически типизирована и имеет сборку мусора. Это означает, что компилятор Java перехватит множество ошибок, которые не будут обнаруживаться в динамически типизированных языках (до времени выполнения), и не будет иметь дело с ошибками сегментации (это не означает, что вы не можете утечки памяти в Java; очевидно, что вы можете). Я считаю, что Java - отличный выбор.

C #

C # язык похож на более современную версию Java. Как и Java, это управляемый (сборщик мусора) промежуточный компилируемый язык, работающий на виртуальной машине. Все остальные языки, перечисленные здесь, кроме C / C ++, также работают на виртуальной машине, но Python, Ruby и т. Д. Интерпретируются напрямую, а не компилируются в байт-код.

В основном C # имеет те же плюсы и минусы, что и Java.

Haskell (и т. Д.)

Наконец, у вас есть функциональные языки: Haskell, OCaml, Scheme / Lisp, Clojure, F # и т. Д. Они думают обо всех проблемах по-разному, и их стоит изучить в какой-то момент, но опять же все сводится к тому, что вы хотите изучить: функциональное программирование или структуры данных? Я бы предпочел изучать одну вещь за раз, чем запутывать проблему. Если вы в какой-то момент выучите функциональный язык (что я бы порекомендовал), Haskell - безопасный и прекрасный выбор.

Мой совет

Выберите Java или C #. У обоих есть бесплатные отличные IDE (Eclipse, Netbeans и IntelliJ Community Edition для Java, Visual Studio Express для C #, Visual Studio Community Edition), которые упрощают написание и выполнение кода. Если вы не используете собственную структуру данных, более сложную, чем массив, и любой объект, который вы пишете, вы узнаете в основном то же самое, что и в C / C ++, но без необходимости фактически управлять памятью.

Позвольте мне объяснить: размер расширяемой хеш-таблицы необходимо изменить, если добавлено достаточное количество элементов. В любой реализации это будет означать что-то вроде удвоения размера резервной структуры данных (обычно массива) и копирования существующих элементов. Реализация в основном одинакова для всех императивных языков, но в C / C ++ вы должны иметь дело с ошибками сегментации, когда вы не выделяете или не освобождаете что-то правильно.

Python или Ruby (неважно, какой именно) были бы моим следующим выбором (и очень близким к двум другим) только потому, что сначала динамическая типизация могла быть проблематичной.

Cletus
источник
1
@cletus: Спасибо за аргументированный ответ! Какие книги DS&A / другие инструкции вы бы порекомендовали (для java или python)?
bguiz
3
@bguiz, возможно, вы захотите задать об этом отдельный вопрос. По этой теме есть несколько вопросов, которые можно найти на stackoverflow.com/search?q=book+data+structures+algoritms. Вы можете уточнить это, добавив [java] или [python] в поиск.
cletus
2
Я бы НЕ использовал Java и C # в основном из-за строгой объектно-ориентированной ориентации, которая здесь просто не нужна. Более того: кого волнует написание универсального кода, когда речь идет об изучении структуры данных? На мой взгляд, либо вы выбираете язык сценариев (Python) и сосредотачиваетесь на высокоуровневом, либо выбираете низкоуровневый язык C / C ++ и пытаетесь увидеть, как он реализован на машинном уровне. Останавливаться между делом не стоит.
Matthieu M.
3
Python сначала не компилируется в байт-код? Новости для меня: docs.python.org/release/2.5.2/lib/bytecodes.html
Адам Кроссленд,
В этом нет смысла: «Это важно, потому что структуры данных, такие как хеш-таблицы, зависят от наличия общего базового класса». Хеш-таблицы полагаются на хешируемые элементы, но особенности того, как это может быть реализовано на языке программирования, не имеют отношения к абстрактному определению структуры данных.
Пены
45

Я бы рекомендовал в Javaосновном потому, что:

  • вывоз мусора
  • Рекомендации
  • богатые коллекции

РЕДАКТИРОВАТЬ: Голосующие вниз, пожалуйста, объясните

codaddict
источник
3
почему все голосуют против?
Мантас Видутис
19
Я считаю, что отрицать это, потому что вам не нравится Java (что, похоже, происходит), безответственно. Возможно, вам не нравится Java, но ее достаточно просто использовать в качестве языка обучения. Итак, +1 от меня.
cletus
7
+1. Не мой выбор, но на самом деле это не страшно. Оценка голосов такая же, как вы предложили COBOL.
Роб Лахлан
4
+1 потому что для новичка: 1. Точно, вам не нужно беспокоиться о выделении / освобождении памяти (по крайней мере, для небольших программ). Вместо этого вы можете сосредоточиться на том, что вам нужно узнать на данный момент. 2. Да, никаких хитрых указателей или указателей на указатели. Не поймите меня неправильно, я люблю C ++. 3. Коллекции в Java, вероятно, являются наиболее совершенным набором структур данных, который я видел. Они действительно должны быть в словаре под структурами данных. :)
crunchdog
9
Если вы не понимаете, как самостоятельно управлять ресурсами, значит, вы мало что узнали о структурах данных.
Алан
30

На мой взгляд, C был бы лучшим языком для изучения структур данных и алгоритмов, потому что он заставит вас писать свои собственные. Это заставит вас понять указатели, динамическое распределение памяти и реализации популярных структур данных, таких как связанные списки, хеш-таблицы и т. Д. Многие из этих вещей вы можете принять как должное в языках высокого уровня (Java, C # и т. Д.) ).

Тейлор Лиз
источник
11
Указатели и динамическое распределение памяти ничему не научат вас о структурах данных и алгоритмах, но они серьезно мешают тому, чего вы можете надеяться достичь.
JD
1
Я согласен. После того, как я познакомился с десятками разных языков и сначала выучил высокоуровневый, высоко абстрагированный, мне было больно, когда я решил изучить C / C ++, и внезапно мне пришлось иметь дело с множеством вещей, которые мне никогда не объясняли. до. Изучение C в первую очередь (а не C ++) - отличный выбор, потому что он показывает, как на самом деле работает машина, и у вас есть все ограничения, которые заставляли создавать структуры данных в первую очередь. Все, что предлагает язык, - это функции (для алгоритмов) и структуры (для структур данных). Разрыв между теорией и языком действительно крошечный.
Рафаэль Бекель
17

Pythonотлично. Легко читается, полнофункциональный. Если вы собираетесь работать с псевдокодом, Python будет вам знаком.

Python уже является предпочтительным языком алгоритмов в Калифорнийском университете в Ирвине , где его описывают следующим образом:
« Python представляет собой ориентированный на алгоритмы язык, который остро необходим в образовании. Преимущества Python включают его синтаксис, похожий на учебник, и интерактивность, которая побуждает к экспериментам. . "

Python также удобен для новичков с Gato , инструментом для построения графиков. Изучение алгоритмов и структур данных - это один из лучших способов, который может помочь, сделав его визуальным, что Gato позволяет легко сделать (без изучения каких-либо сложных графических библиотек)

Мантас Видутис
источник
@mvid: Есть ли книга DS & A на основе Python, которую вы бы порекомендовали?
bguiz
1
@bguiz: Хотя я лично ее не читал, существует эта бесплатная электронная книга, посвященная алгоритмам и структурам данных с использованием объектно-ориентированного программирования в Python: brpreiss.com/books/opus7
Мантас Видутис
Python
хорош
Пробелы в качестве разделителя - это круто!
Марсель Вальдес Ороско,
Мне лично не нравится Python из-за синтаксического использования отступов. Я считаю, что найти глупые ошибки из-за несовпадения труднее, чем для синтаксиса, основанного на фигурных скобках и т.п., поддерживаемого дополнительным выравниванием, подобным nroff.
Майкл
13

Если цель состоит в том, чтобы узнать только о структурах данных и алгоритмах , я бы сказал, JavaScript. Вы можете запустить свой код в браузере. У вас очень гибкая обработка объектов, и вы можете полностью сосредоточиться на структурах данных и алгоритмах, а не на управлении памятью, языковыми конструкциями или другими вещами, которые отвлекут внимание от реальной информатики, которую вы изучаете.

Бонусом также является то, что вы можете легко визуализировать различные структуры данных, используя браузер для визуализации графиков и деревьев с использованием DOM и Canvas.

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

Эрнелли
источник
+1, потому что JavaScript позволяет легко изучать функциональное программирование и имеет широкую применимость, позволяющую разрабатывать веб-приложения с его помощью.
Дэн Даскалеску
Совершенно верно. Я тестирую свой код во фрагменте инструментов разработчика. Кроме того, я могу аналогичным образом писать в нем свои собственные структуры данных. В нем нет связанного списка или какой-либо другой структуры. Все просто объект. Если я не занимаюсь соревновательным программированием, он работает, чтобы изучить двоичный поиск, trie и все другие концепции. Нет?
HalfWebDev
полностью согласен, давайте сосредоточимся на логике без особых церемоний и голого синтаксиса.
jtroconisa
8

Если вы хотите пойти по пути наименьшего сопротивления, тогда Python. В нем будет минимум ненужной плиты котла и тому подобного.

В идеале я бы хотел изучить алгоритмы на C, чтобы вы могли узнать, что происходит на уровне памяти; Я бы также хотел изучить алгоритмы на функциональном языке, чтобы вы могли увидеть, как похожие алгоритмы работают с постоянными структурами данных.

Знаменитые книги Кнута содержат большое количество кода ассемблера (придуманной платформы). Это рекомендуется, если вы хотите быть супер-хардкорным. Лично я работал с C, когда работал над своим классом алгоритмов (раскрытие: это было всего пару лет назад). Иногда я работаю над некоторыми проблемами в Knuth, но я не знаю, буду ли я полностью использовать MMIX в качестве языка для изучения алгоритмов. Я чувствую, что это немного перебор.

РЕДАКТИРОВАТЬ : Это также зависит от того, с чем вы знакомы. Если вы хотите начать работать с текстом алгоритмов прямо сейчас, и вы никогда особо не работали с C, то Python, безусловно, правильный ответ. Вы хотите, чтобы язык не был огромным препятствием, которое нужно преодолеть, потому что вы хотите получать от этого удовольствие. Я знаю, что сделал.

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

Роб Лахлан
источник
@ Роб Лахлан: Есть ли книга DS & A на основе Python, которую вы бы порекомендовали?
bguiz
@bguiz: большинство хороших книг по алгоритмам, которые мне нравятся, не зависят от языка - Кормен и др., Кляйнберг и Тардос. Я бы не стал выбирать ни одного на основе языка.
Роб Лахлан
8

Я бы предложил Аду. В нем есть функции для конструкций данных, не встречающиеся в других языках, такие как проверки диапазона. type Day is range 1 .. 31;Кроме того, он имеет очень строгую проверку во время компиляции и выполнения (если вы не решите отключить ее), что упрощает поиск ошибок в вашей реализации.

Дэниел Роуз
источник
8

Оберон-2 или Компонентный Паскаль . Последний - надмножество первого.

Эйнштейн однажды сказал: «Сделайте это как можно проще, но не проще». Эта фраза была выбрана профессором Никлаусом Виртом в качестве эпиграфа к исходному отчету на языке Оберон. И это верно для упомянутых выше потомков Оберона.

Когда дело доходит до совершенства языка программирования, я люблю цитировать Антуана де Сент-Экзюпери: «Дизайнер знает, что он достиг совершенства, не тогда, когда больше нечего добавить, но когда больше нечего убирать». . Вирт, даже если этого и не добился, находится на правильном пути. В «линейке языков программирования вирт» (Алгол -> Паскаль -> Модула-2 -> Оберон -> Оберон-2) каждый последующий язык проще и в то же время мощнее предыдущего.

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

Когда вы хотите изучить алгоритмы и структуры данных, вы имеете в виду это. Но если ваш язык «мощный» (имеет множество функций, таких как C ++, C #, Java, Python, ...), вы потратите много времени на изучение языка, а не алгоритмов и структур данных. За деревьями леса не увидишь. =) Вы можете думать о деревьях как о элементах синтаксиса (и любых других функциях), а о лесах как о важном понятии (любой алгоритм, структура данных, может быть ООП, что угодно). Чем больше функций (деревьев) у вас есть на вашем языке, тем сложнее становится задача сделать шаг назад и понять концепции (увидеть лес).

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

Также во многих книгах по алгоритмам и структурам данных используется псевдокод, подобный Algol / Pascal, и будет легко преобразовать примеры на этих языках. И вы можете напрямую использовать примеры из книги Вирта «Алгоритмы и структуры данных». Издание Оберон (2004 г.), PDF (1,2 МБ).

Некоторые дополнительные ссылки:

Дикий кот
источник
@kemiisto: спасибо за uniuue и роман, ответ - и аналогии! Я тоже посмотрю на Оберон-2.
bguiz
2
Английская версия пословицы - «За деревьями леса не видно».
Дэниел Роуз
6

«Если ваш единственный инструмент - молоток, тогда все ваши проблемы будут похожи на гвозди»

Выучите хотя бы несколько языков.

Также ваш выбор зависит от вашей цели.

Хобби? Работа в мире Windows? Семейство Linux / UNIX?

Типы приложений: бизнес или наука; драйверы оборудования или приложения?

Настольные приложения или веб-приложения?

У меня есть несколько предложений для вас.

(а) определенно выучите J (бесплатно с jsoftware.com; преемник APL; и J, и APL - творения Кена Айверсона, победителя Тьюринга ... Премия Тьюринга подобна Нобелевской премии в области вычислений).

(б) если вы работаете в мире Windows, начните с C #, потому что многое в .NET выполняется на C #. Если можете, получите копию книги Тома Арчера "Inside c #" в Microsoft Press. Вы можете получить бесплатную систему разработки на C #, загрузив экспресс-версию Microsoft.

(c) научитесь использовать TDD / BDD ... независимо от языка, сначала вы напишете небольшой тест, называемый модульным тестом; затем вы пишете производственный код для прохождения модульного теста; шаг за шагом ... это не только язык, который вы используете, но и методология.

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

(д) за пределами мира Windows я бы рекомендовал c ++.

Нет лучшего языка.

Если бы речь шла только о языке, программирование было бы проще.

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

Одно можно сказать наверняка: если вы собираетесь стать программистом, у вас, скорее всего, никогда не закончится обучение.

GerryLowry
источник
Структуры данных @bguiz могут быть полностью независимыми от языка; это одна из причин для изучения разных языков. Вы также столкнетесь с тонкими различиями, которые могут вызвать разочарование и даже горе; Например, имя типа данных: бит для SQL Server имеет значение bool для C # и Boolean для vb. размер типа данных тоже варьируется; Например, int в C # имеет фиксированное 32-битное значение, тогда как в C ++ его размер и, следовательно, емкость хранилища зависят от платформы. Наборы символов также влияют на размер вашей структуры данных; примеры, 7-битный ASCII, 8-битный ASCII, Unicode. Тогда есть фиксированный размер против изменения и так далее.
gerryLowry
«структуры данных могут быть практически полностью независимыми от языка». Чтобы реализовать наиболее чисто функциональные структуры данных на языке, который не обеспечивает сборку мусора, вам в основном придется написать сборщик мусора. Это серьезное препятствие.
JD
Когда вы освоите объектно-ориентированный подход, попробуйте охватить декларативное программирование.
greybeard
4

Вы можете оценить язык с алгебраическими типами данных и сопоставлением с образцом, такой как Standard ML, OCaml, F # или Haskell. Например, вот функция для ребалансировки красно-черного двоичного дерева поиска, написанная на OCaml / F #:

let balance = function
  | R(R(a, x, b), y, c), z, d | R(a, x, R(b, y, c)), z, d
  | a, x, R(R(b, y, c), z, d) | a, x, R(b, y, R(c, z, d)) ->
      R(B(a, x, b), y, B(c, z, d))
  | a, x, b -> B(a, x, b)
JD
источник
10
Ваш сарказм приветствуется, сэр.
ergosys 05
4

Я думаю, что Lisp стоит изучить.

Мой первый университетский курс программирования был на Лиспе. До этого я 10 лет писал программы на нескольких языках. Я думал, что первый курс программирования будет скучным, но ошибался.

Лисп - очень интересный язык, потому что у него очень простой синтаксис. Акцент смещается с синтаксиса на функциональность. Стиль функционального программирования также является чрезвычайно ценным предметом для изучения. После моего курса Lisp я обнаружил, что пишу программы на C ++ совершенно новым, лучшим способом, благодаря новым концепциям, которым меня научил Lisp.

Lisp также использует то же представление для кода и данных, что открывает интересный дизайн алгоритма с кодом, сгенерированным на лету, а затем выполненным.

Андерс Абель
источник
2

Я могу ошибаться, но разве структуры данных и алгоритмы не независимы от языков программирования?

В конце концов, структуры данных - это просто способ организации данных; любой язык высокого уровня поддержит это. Конечно, в некоторых языках будут механизмы, реализующие базовые структуры данных (например, Collections Framework в Java или C ++ STL), но это не мешает вам программировать структуру данных на языке программирования по вашему выбору. Более того, алгоритмы написаны в псевдокоде, что делает их независимыми от языка.

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

Пран
источник
1
@Pran: Я знаю, что алгоритмы находятся в псевдокоде, но псевдокод не компилируется. Я разбираюсь в типах, поэтому, чтобы по-настоящему понять концепции, мне нужно было бы написать код на языке, который может компилироваться и запускаться. Поэтому мой вопрос на самом деле заключается в том, какой язык лучше всего подходит для этого, в том смысле, что у каждого языка должны быть свои плюсы и минусы, что делает некоторые из них более подходящими для изучения DS&A, чем другие.
bguiz
@Pran: «Я могу ошибаться, но разве структуры данных и алгоритмы не независимы от языков программирования?». Если язык не предоставляет GC, возможно, вам придется его написать.
JD
2

Любой язык, кроме уродливого C ++, подойдет.

Джереми Хосе
источник
0

Я предпочитаю C ++ :)

Prasoon Saurav
источник
19
-1 C ++ - ужасный язык для обучения (и, возможно, вы можете убрать квалификатор "обучение" из этого утверждения).
cletus
4
Ему не нужно изучать темные уголки C ++, чтобы кодировать свои алгоритмы на C ++. C ++ - это прекрасно.
Prasoon Saurav
9
поэтому вы думаете, что это хорошая идея - попробовать написать класс для DS на C ++ и уловить различия между конструктором копирования и переопределением оператора равенства, ссылками и указателями, выходящими за пределы области видимости, утечкой памяти из-за неправильного нового / удаления использование и т. д.? Все это очень важно для C ++.
cletus
5
но дело в том, что вы НЕ ДОЛЖНЫ изучать эти вещи на python или java. C ++ требует гораздо больших начальных вложений и никоим образом не более ценен для функции, запрошенной OP,
Мантас Видутис
2
Какие-либо веские причины не рекомендовать Javascript для изучения @cletus?
HalfWebDev