Pull to refresh
6
0
Send message

Поиск подстроки. Алгоритм Кнута–Морриса-Пратта

Reading time3 min
Views94K
В задачах поиска информации одной из важнейших задач является поиск точно заданной подстроки в строке. Примитивный алгоритм поиска подстроки в строке основан на переборе всех подстрок, длина которых равна длине шаблона поиска, и посимвольном сравнении таких подстрок с шаблоном поиска. По традиции шаблон поиска или образец принято обозначать как needle (англ. «иголка»), а строку, в которой ведётся поиск — как haystack (англ. «стог сена»). На языке Python примитивный алгоритм выглядит так:

index = -1
for i in xrange(len(haystack)-len(needle)+1):
    success = True
    for j in xrange(len(needle)):
        if needle[j]<>haystack[i+j]:
            success = False
            break
    if success:
        index = i
        break
print index


Обозначим n=|haystack|, m=|needle|. Простейший алгоритм поиска даже в лучшем случае проводит n–m+1 сравнений; если же есть много частичных совпадений, скорость снижается до O(n*m).

Рассматриваемый далее алгоритм хотя и имеет невысокую скорость на «хороших» данных, но это компенсируется отсутствием регрессии на «плохих». Алгоритм Кнута-Морриса-Пратта является одним из первых алгоритмов с линейной оценкой в худшем случае.
Читать дальше →

Разбор всех задач и результаты Яндекс.Алгоритма

Reading time17 min
Views116K
Буквально пару часов назад в Санкт-Петербурге завершился открытый чемпионат по программированию Яндекс.Алгоритм 2013. Состязания состояли из нескольких онлайн-раундов по 100 минут, за победу боролись более 3000 программистов из 84 стран. По результатам трёх отборочных раундов в финал вышли 25 лучших.

image

Финалисты должны были решить шесть алгоритмических задач за 100 минут. Первое место занял недавний победитель ACM ICPC 2013 в составе команды НИУ ИТМО Геннадий Короткевич (tourist), который набрал меньше всего штрафного времени. Второе место досталось выпускнику НИУ ИТМО Евгению Капуну (eatmore). Третье место занял представитель Тайваня Ши Бисюнь.

В подготовке заданий для чемпионата участвовали специалисты из нескольких стран: России, Беларуси, Польши и Японии. Главными составителями задач стали разработчики минского офиса Яндекса (как и все сотрудники компании, к участию в состязаниях они не допускались). Мы попросили всех авторов разобрать задания, которые они подготовили для участников Яндекс.Алгоритма. Кстати, все задачи не удалось решить никому, лучший результат — три решённые задачи — показали только три участника.
Читать дальше →

Об одной изящной конструкции

Level of difficultyMedium
Reading time7 min
Views77K

Введение


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

Распечатать в порядке возрастания все несократимые дроби, знаменатель которых не превосходит заданного числа $n, \, n \le 100$.

Когда я прочитал условие задачи до конца, она не показалась мне сложной (она таковой и не является). Первое, что пришло мне в голову — это просто перебрать все знаменатели от $2$ до $n$ и для каждого знаменателя перебрать числители от $1$ до знаменателя, при условии, что числитель и знаменатель взаимно просты. Ну, а затем остается отсортировать их по возрастанию.

Такое решение верное, и задача прошла все назначенные ей тесты. Однако мой преподаватель сказал, что задачу можно решить намного красивее. Так я и познакомился с замечательной конструкцией: деревом Штерна — Броко.
Читать дальше →

Распознавание рукописного ввода

Reading time4 min
Views23K
Введение


В данной статье пойдет речь о методе распознавания рукописного ввода путем анализа всех точек плоскости и перебора всевозможных комбинаций с целью отыскать наилучшее наложение контрольных точек на ранее описанные фигуры. Поясню.
Рукописный ввод — это рисование мыслимым «пером» определенной фигуры. Рисование в компьютерных системах — это сохранение в графической памяти информации обо всех пикселях графического контекста. «Точка на плоскости» в математике — понятие абстрактное. В компьютерной же графике за этим понятием скрывается «пиксель». Данный алгоритм распознавания будет анализировать предоставленный ему набор точек( пикселей ) и пытаться в нем отыскать наиболее возможную и похожую фигуру. Фигура, в свою очередь, это каркас, содержащий лишь основные( контрольные ) точки, делающие фигуру уникальной.

Матчасть


Вообще говоря, сердце алгоритма — всем известная со времен школы Теорема Косинусов, являющаяся обобщенной теоремой Пифагора. Зная координаты трех точек плоскости и их порядок «появления» на ней, мы можем с легкостью определить угол, описанный этими точками( Вершина угла — вторая по счету точка ):

image

A( x1;y1 )
B( x2;y2 )
C( x3;y3 )

расстояния между точками находятся по теореме Пифагора

a^2 = b^2 + c^2 — 2*b*c*cos(ALPHA)
cos(ALPHA) = (b^+c^-a^) / 2*b*c


Зная косинус, величину угла легко можно вычислить.

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

  1. Мы берем первую и последнюю точки каркасов фигур. Уже две есть, осталось отыскать третью ( для нахождения величины угла ).
  2. Поиск третьей осуществляется перебором все последующих точек после первой. Решение включать точку в предполагаемый каркас фигуры принимается на основе двух анализов:
    • Попытка подставить точку в угол( в качестве третьей, заключительной ) и проверить его на соответствие величине того же угла в каркасе реальной фигуры.
    • Проверить отношение сторон получившегося угла с тем же отношением сторон угла в каркасе реальной фигуры.


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

Если, допустим, у нас есть несколько анализируемых каркасов, например, «8» и «6». И результат алгоритма распознавания: «8»-80%, «6» — 90%, то решение принимается в пользу той фигуры, в каркасе которой присутствует больше контрольных точек, т.е в пользу восьмерки.

Процент сходства набора точек с точками в каркасе высчитывается просто: суммируются все точки, которые сошлись с теми же точками в каркасе и находится отношение. Допустим, если в каркасе N контрольных точек, а у нас сошлось M, то процент сходства — M / N * 100

Читать дальше →

Что можно узнать о кандидате по тестовому заданию

Reading time9 min
Views87K
Какое-то время назад по Хабру прокатилась волна статей о поиске работы и прохождению собеседований. Многократно высказались и работодатели и соискатели. Но, к сожалению, не была в достаточной степени затронута тема тестовых заданий.

Ведь, тестовое задание не ограничивается категориями «выполнил» и «не выполнил». Внимательно наблюдая за процессом и изучая финальный результат, можно в итоге многое сказать о человеке ни дня с ним вместе не поработав. А порой, и научиться чему-то новому.

Предлагаю вашему вниманию тестовое задание, которое я уже довольно давно даю кандидатам в компании, где я работаю:

На экране есть сетка M на N из цветных квадратиков. Нужно реализовать на этой сетке следующий эффект — по клику слева направо со скоростью V пробегает волна, меняя цвет квадратиков на другой (единый для всей волны). Эффект должен работать при любых значениях M, N, V. Волна начинается всегда у левой стенки. Одновременно может идти несколько волн разного цвета.
Анимационный пример: http://dl.dropbox.com/u/3601116/wave.swf (покликать по флэшке).


Я не сомневаюсь, что это задание с легкостью сделают все программисты посетители Хабра.

А у меня получилась следующая статистика:

  1. В итоге, задание взяли чуть больше 20 человек.
  2. Пара человек ничего не сделали.
  3. Половина из оставшихся (по моим критериям) с ним не справились.
  4. Кандидаты четко разделились на весьма интересные группы.

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

Разбор задач финала чемпионата мира про программированию ACM ICPC 2013

Reading time25 min
Views122K
На прошедшем неделю назад чемпионате мира по командному программированию ACM ICPC 2013 было 11 задач, одну из которых за отведённое время не смогла решить правильно ни одна из команд.

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

В этом году на ACM ICPC был 21 аналитик из Швеции, Нидерландов, США, Словакии, Беларуси и России. И 10 из них были из Яндекса. Все они в разные годы были призёрами ICPC. Специально для Хабра они разобрали все задания чемпионата.

Разбор задачи «Матрёшка» во время трансляции ACM ICPC 2013
Читать дальше →

Как сделать ваше приложение быстрым: профильная оптимизация C++

Reading time6 min
Views17K
Профильная оптимизация это очень интересный способ оптимизации кода приложения в среде выполнения (в команде разработчиков Visual C этот метод называют POGO или PGO, от английского Profile Guided Optimization). Впервые профильная оптимизация была применена в конце 90-х исследовательскими группами в Visual C и Microsoft. Тогда она была рассчитана для архитектуры Itanium. Затем PGO была включена в состав Visual Studio C/C++ 2005. На сегодня это основной процесс оптимизации, значительно повышающий производительность приложений Microsoft и других разработчиков.
В этом посте будет рассказано, как создавать более быстрые и высокопроизводительные нативные приложения. Для начала, познакомимся ближе с PGO, а затем рассмотрим на примере (симуляция NBody), как с помощью нескольких простых шагов можно применить этот процесс оптимизации в ваших приложениях. Для работы используйте исходный код из примера. Для сборки проекта вам понадобится DirectX SDK.
Читать дальше →

Смешивание текстур ландшафта

Reading time3 min
Views91K


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

Статья рассчитана на начинающих разработчиков игр.
Читать дальше →

Отчёт со Всероссийского Открытого Чемпионата по программированию

Reading time4 min
Views37K

Первый день: как видите, многие финалисты со своими ноутбуками

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

Кто и откуда приехал?


Участвовало 3500 программистов со всей России, из стран СНГ и совсем немного — из других стран. К первому туру было отобрано 2000 участников, ко второму — 400, а в финал в Москве вышло 50 человек. Уровень в этом году был явно выше чем в прошлом: либо сказались тренировки и то, что турнир набирает известность, либо то, что в игру включились гости из других стран. Приезжали участники финалов прошлых лет.

В финал попало 16 москвичей, 14 петербуржцев, по двое жителей Екатеринбурга, Нижнего Новгорода, Саратова, один участник приехал из Новосибирска. Также в финал вышли по трое из Беларуси, Польши, Украины и даже один человек из Японии. По правилам турнира мы оплачивали дорогу всем, кроме жителей Польши и Японии, а проживание оплатили каждому участнику.
Читать дальше →

Russian Code Cup 2013 – разбор задач 2-го квалификационного раунда

Reading time10 min
Views16K

Вот и прошел второй квалификационный раунд Russian Code Cup. Майские праздники, многие разъехались кто куда… Однако для того чтобы пройти в отборочный тур, участникам второго квалификационного раунда пришлось побороться.
Как и в предыдущем раунде, зарегистрировавшихся было больше, чем приславших решения. Поэтому в числе принявших участие мы отражаем только тех, кто прислал хотя бы одно решение.
Майская жара и 5 задач, которые требуется решить за 2 часа:
  • задача A. Молекула
  • задача B. Морской бой
  • задача C. Пробка
  • задача D. Таблица
  • задача E. Космическая экспедиция

Условия и решение — под катом.
Читать дальше →

Скрытые цепи Маркова, алгоритм Витерби

Reading time5 min
Views60K
Нам нужно реализовать детектор лжи, который по подрагиванию рук человека, определяет, говорит он правду или нет. Допустим, когда человек лжет, руки трясутся чуть больше. Сигнал может быть таким:

Исходный сигнал

Интересный метод, описан в статье «A Tutorial on Hidden Markov Models and Selected Applications in Speech Recognition» L.R. Rabiner, которая вводит модель скрытой цепи Маркова и описывает три ценных алгоритма: The Forward-Backward Procedure, Viterbi Algorithm и Baum-Welch reestimation. Несмотря на то, что эти алгоритмы представляют интерес только в совокупности, для большего понимания описывать их лучше по отдельности.
Читать дальше →

Две задачки для собеседования разработчиков

Reading time4 min
Views98K
Раньше мне часто приходилось собеседовать людей на различные позиции, большая часть из них были разработчики приложений и баз данных. Процесс этот довольно утомительный, т.к. программисты люди смелые, творческие, любознательные и целеустремленные.
В моей практике были всякие вопросы. В статье я выделю три основных типа и расскажу, на чем я в итоге остановился и почему.
Читать дальше →

Популяционный алгоритм, основанный на поведении косяка рыб

Reading time7 min
Views36K
В рамках данного сообщества неоднократно обсуждались генетические алгоритмы и их применение на практике. В этой статье я хотел бы поделиться относительно новым методом оптимизации функций, основанным на поведении косяка рыб в условиях поиска пищи.
Читать дальше →

Russian Code Cup 2013: разбор задач первого квалификационного раунда

Reading time11 min
Views22K

В субботу, 13 апреля 2013 года, в 19 часов состоялся первый квалификационный тур. Несмотря на, казалось бы, несчастливую дату, для многих этот день оказался, наоборот, очень удачным.
В этом посте мы кратко расскажем об итогах первого квалификационного раунда и подробно разберем задачи, которые мы предлагали участникам.
В сегодняшнем разборе участвуют:
  • Олимпиада в Гномляндии
  • Один день Антона Сергеевича и его студентов
  • Проблемы хранения млурана в ядерной лаборатории Флатландии
  • Актуальный вопрос защиты планеты от метеоритов
  • Телепорты и то, какие препятствия они создают для кладоискателей

Читать дальше →

Особенности строк в .NET

Reading time10 min
Views110K
Строковый тип данных является одним из самых важных в любом языке программировании. Вряд ли можно написать полезную программу не задействовав этот тип данных. При этом многие разработчики не знают некоторых нюансов связанных с этим типом. Поэтому давайте рассмотрим кое-какие особенности этого типа в .NET.

Итак, начнем с представления строк в памяти


В.NET строки располагаются согласно правилу BSTR (Basic string or binary string). Данный способ представления строковых данных используется в COM (слово basic от языка программирования VisualBasic, в котором он первоначально использовался). Как известно в C/C++ для представления строк используется PWSZ, что расшифровывается как Pointer to Wide-character String, Zero-terminated. При таком расположении в памяти в конце строки находится null-терминированный символ, по которому мы можем определить конец строки. Длина строки в PWSZ ограничена лишь объемом свободной памяти.
Читать дальше →

StringBuilder прошлое и настоящее

Reading time13 min
Views65K

Вступление


Моя прошлая статья была посвящена особенностям строкового типа данных String в .NET. Эта статья продолжает традицию, однако на этот раз мы рассмотрим класс StringBuilder.

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

string s = string.Empty;
for (int i = 0; i < 100; i++)
 {
    s += "T";
 }
Читать дальше →

Алгоритм Эллера для генерации лабиринтов

Reading time5 min
Views155K
Это топик-перевод статьи Eller's Algorithm. В ней рассказывается о способе программной генерации лабиринтов. Дальнейшее повествование идет от лица автора.

 __ __ __ __ __ __ __ __ __ __ __ __ __ __ __  
|__   |__       __ __|__   |   __|  |  |  |  |
|__   |__   |__|   __ __|   __ __      |     |
|        |  |  |     |  |__      |__|  |  |  |
|__|__|  |  |   __|   __|__   |   __|__|  |__|
|   __|  |     |__ __ __|  |  |__|  |     |  |
|  |  |  |  |__|  |__   |  |   __|__ __|  |  |
|  |__    __    __ __    __|  |   __   |  |  |
|  |  |  |  |      __|  |   __|  |  |__|  |  |
|  |     |     |__   |  |  |  |  |  |__    __|
|  |  |__|__|__ __|  |     |  |  |      __|  |
|__ __|  |  |  |__   |__|   __|     |   __ __|
|   __|  |   __|__      |__   |__|  |__    __|
|  |  |     |  |     |__|  |   __    __|   __|
|   __|  |__ __|__|      __|  |  |     |  |  |
|   __ __   |      __|__|  |__   |  |  |__|  |
|__ __ __|__ __|__ __ __ __ __|__|__|__ __ __|


Алгоритм Эллера позволяет создавать лабиринты, имеющие только один путь между двумя точками. Сам по себе алгоритм очень быстр и использует память эффективнее, чем другие популярные алгоритмы (такие как Prim и Kruskal), требуя памяти пропорционально числу строк. Это позволяет создавать лабиринты большого размера при ограниченных размерах памяти.

Читать дальше →

Минифест (манифест разработчиков-минималистов)

Reading time6 min
Views50K
От переводчика

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

Снова прошу прощения за отсутствие перевода словосочетания “computer science”.


Кратко


  • Боритесь за закон Парето, следите за тем, чтобы 20% вашего труда давало вам 80% результата;
  • Расставляйте приоритеты, ведь минимализм нужен для того, чтобы делать то, что нужно, а не распыляться по мелочам;
  • Лучшее — враг хорошего: сначала просто сделайте, потом сделайте правильно, потом сделайте лучше;
  • Убивайте в зародыше, не бойтесь начать всё сначала. Чем быстрее ошибётесь, тем быстрее научитесь;
  • Повышайте свою ценность. Постоянно думайте о том, чем можно помочь команде, — и развивайтесь в этом направлении;
  • Сперва основы. Мыслите последовательно, ориентируясь на лучшие практики мира Computer Science;
  • Посмотрите с разных сторон. Простое получается тяжелее, чем сложное, поэтому включайте воображение;
  • Синтаксис — основа взаимодействия. Мы пишем код для людей, а не для машин;
  • Не запутывайте. Старайтесь проектировать слоями, по мере возможности не зависящими друг от друга;
  • Вычищайте оставленное-на-всякий-случай. Минимализм борется с отвлекающим от основного.

Читать дальше

Алгоритм сортировки Timsort

Reading time6 min
Views162K
Timsort, в отличии от всяких там «пузырьков» и «вставок», штука относительно новая — изобретен был в 2002 году Тимом Петерсом (в честь него и назван). С тех пор он уже стал стандартным алгоритмом сортировки в Python, OpenJDK 7 и Android JDK 1.5. А чтобы понять почему — достаточно взглянуть на вот эту табличку из Википедии.



Среди, на первый взгляд, огромного выбора в таблице есть всего 7 адекватных алгоритмов (со сложностью O(n logn) в среднем и худшем случае), среди которых только 2 могут похвастаться стабильностью и сложностью O(n) в лучшем случае. Один из этих двух — это давно и хорошо всем известная «Сортировка с помощью двоичного дерева». А вот второй как-раз таки Timsort.

Алгоритм построен на той идее, что в реальном мире сортируемый массив данных часто содержат в себе упорядоченные (не важно, по возрастанию или по убыванию) подмассивы. Это и вправду часто так. На таких данных Timsort рвёт в клочья все остальные алгоритмы.
Читать дальше →

GamePlay 3D Framework — лёгкий старт в кроссплатформенную разработку 3D игр

Reading time13 min
Views32K
Доброе время суток, уважаемые хабражители!

Прослушав курс по компьютерной графике в университете и вдоволь наигравшись с OpenGL, я решил, что пора бы уже двинуться дальше и попробовать себя в разработке игр. Писать с нуля свой движок, прямо скажем, не очень-то хотелось. Главной целью было скорее посмотреть как это делается, вынести уроки и может быть создать что-то на базе выбранного движка. Беглый поиск показал, что с открытыми кроссплатформенными движками немного туго. У одного проблемы с Linux, Windows или Mac OS, у другого со свежими версиями мобильных ОС, третий почти заброшен… Но я-таки наткнулся на один очень привлекательный экземпляр, о котором и хочу поведать в этой статье.

gameplay

Имя этому фреймворку — GamePlay 3D. Информации о нём на просторах интернета не очень много, чего уж говорить про рунет. Это open source фреймворк написанный на C++ для программирования игр на C++ со всеми вытекающими из этого достоинствами и недостатками. Авторы проекта позиционируют его как универсальный инструмент, эдакий аналог cocos2d для 3D игр. Чтобы начать писать на GamePlay 3D не нужно обладать глубокими знаниями OpenGL, GLSL или математики 3D графики, однако все мы понимаем, что для достижения хорошего результата от этого никуда не деться. Подробности и небольшой пример для старта под катом.

Читать дальше →

Information

Rating
Does not participate
Location
München, Bayern, Германия
Registered
Activity

Specialization

Fullstack Developer, Application Developer
Git
SQL
OOP
C#
.NET Core
.NET
ASP.Net
Database