#1. Алгоритм Кнута-Морриса-Пратта (КМП-алгоритм) | Алгоритмы на Python

แชร์
ฝัง
  • เผยแพร่เมื่อ 2 ม.ค. 2025

ความคิดเห็น • 119

  • @АлексейСергиевский-в6й
    @АлексейСергиевский-в6й 3 ปีที่แล้ว +205

    Сергей, спасибо большое. Вы так разорите товарищей с платных курсов

    • @kadabrochka1252
      @kadabrochka1252 7 หลายเดือนก่อน +5

      Не разорит. Практически тот же самый курс и материал есть на канале у Roman Tsarev (и выложен он еще 6 лет назад). Однако, мне нравится манера Сергея излагать материал.

  • @mrfang5908
    @mrfang5908 2 ปีที่แล้ว +6

    Увидел свежее видео, пошел в плейлист, Сергей такое ощущение что вы прям выкладываете что мне надо, спасибо, хорошо объясняете

  • @MarchelloCSKAMoscow
    @MarchelloCSKAMoscow 3 ปีที่แล้ว +25

    Сергей , вашей продуктивности можно позавидовать!

  • @s979n2
    @s979n2 3 ปีที่แล้ว +25

    Спасибо за труд! Отличное объяснение

  • @АнастасияГребнева-э7м
    @АнастасияГребнева-э7м 2 ปีที่แล้ว +5

    Сергей, спасибо большое! Очень подробное и понятное объяснение! Каждый момент, который бы мог стать сложным, с Вашей подачей абсолютно понятен. Благодаря Вашим курсам и видеороликам получаю зачеты и пятерки на экзаменах в университете =) Спасибо еще раз)

  • @logistloglab5243
    @logistloglab5243 ปีที่แล้ว +2

    Надеюсь, что дорос до этого плейлиста. Сергей, спасибо!)

  • @Александр-ы1л2и
    @Александр-ы1л2и 4 หลายเดือนก่อน

    Я в шоке с качества объяснения. Очень понятно и интересно. Спасибо огромное!

  • @sergey6453
    @sergey6453 2 ปีที่แล้ว +3

    Спасибо, очень доступно объясняете, прекрасная наглядная презентация, а также большое количество примеров и пояснений. Все в миг стало понятно!

  • @donfedor007
    @donfedor007 3 ปีที่แล้ว +10

    Добрый день! не смотрел пока весь в Flask и Django, но лайк однозначно!!!

  • @РоманБойко-б1т
    @РоманБойко-б1т ปีที่แล้ว +2

    Благодаря вам понял тонкий момент КМП, спасибо большое!

  • @luckytima2315
    @luckytima2315 3 ปีที่แล้ว +7

    Ой супер вообще ))) Надеюсь будет много видео в данной рубрике :))

  • @evgenybratkovsky1486
    @evgenybratkovsky1486 11 หลายเดือนก่อน +2

    Очень толково объясняете. Спасибо!

  • @Noklee
    @Noklee ปีที่แล้ว +1

    Начал смотреть за пару дней до олимпиады. Круть

  • @ОлесяКравцова-й4ш
    @ОлесяКравцова-й4ш 8 หลายเดือนก่อน +1

    Спасибо большое! Наконец-то я поняла этот алгоритм и связь префиксов и суффиксов)

  • @nikolaytalkov2525
    @nikolaytalkov2525 2 ปีที่แล้ว +1

    Класс испытал истинное удовольствие от просмотра видео, четко ясно информативно. Спасибо тебе, так держать, молодец что снимаешь такие познавательные видео

  • @study_land_pinsk1004
    @study_land_pinsk1004 2 ปีที่แล้ว +3

    Сергей, вы вылучший! Пол года уже изучаю Python и ML по разным русскоязычным и англоязычным курсам.
    Как устроюсь на работу обязательно отблагодарю "$ THANKS" )

    • @ВалерийКран
      @ВалерийКран ปีที่แล้ว

      Устроился?

    • @fyyann5944
      @fyyann5944 ปีที่แล้ว

      Тоже интересно
      Решил изучать питон, ибо тема интересна и привлекает идея работать в айти

  • @ВикторЖигурда
    @ВикторЖигурда 3 ปีที่แล้ว +2

    На счет знание алгоритмов это в первую очередь я с вами соглашусь уважаемый

  • @levinowak
    @levinowak ปีที่แล้ว +1

    Коммент в поддержку! Лучшее объяснение и отличная подача

  • @ЕрвандАгаджанян-в3к
    @ЕрвандАгаджанян-в3к 3 ปีที่แล้ว +5

    Этот алгоритм легче понять, если пропустить через дебаггер в пайчарме. Я его перезаписал с более наглядными названиями переменных. Если поставить на 28й строчке точку дебага и пошагово пройтись через Step Over (fn + F8 на маке) то все будет четко понятненько:
    ```
    entry = "лилила"
    text = "лилилось лилилась"
    len_entry = len(entry)
    len_text = len(text)
    def get_pi():
    pi = [0] * len_entry
    j, i = 0, 1
    while i < len_entry:
    if entry[j] == entry[i]:
    pi[i] = j + 1
    i += 1
    j += 1
    else:
    if j == 0:
    pi[i] = 0
    i += 1
    else:
    j = pi[j - 1]
    return pi
    text_pointer = 0
    entry_pointer = 0
    while text_pointer < len_text:
    if text[text_pointer] == entry[entry_pointer]:
    text_pointer += 1
    entry_pointer += 1
    if entry_pointer == len_entry:
    print("образ найден")
    break
    else:
    if entry_pointer > 0:
    pi = get_pi()
    entry_pointer = pi[entry_pointer - 1]
    else:
    text_pointer += 1
    if text_pointer == len_text and entry_pointer != len_entry:
    print("образ не найден")
    ```

  • @alexk.6243
    @alexk.6243 ปีที่แล้ว +1

    Классный урок, интересная и содержательная подача!

  • @ryzhakovalexey5037
    @ryzhakovalexey5037 3 ปีที่แล้ว +38

    Я до сих пор не понимаю, почему так мало просмотров у тебя на канале

    • @sainco3036
      @sainco3036 3 ปีที่แล้ว +7

      Скоро будет много просмотров, а пока можно поддержать автора спонсорством.

    • @ДмитрийЧернов-ъ2ф
      @ДмитрийЧернов-ъ2ф 2 ปีที่แล้ว +3

      Учеба дело очень энергозатратное)) Мозг обывателя гораздо охотнее поглощает тик-ток))

    • @Grigoryshaw
      @Grigoryshaw ปีที่แล้ว

      Ответ прост: очень мало заинтересованных этой темой

  • @chimchimsterschannel161
    @chimchimsterschannel161 2 ปีที่แล้ว +5

    Сложно с первого раза понять) сегодня реализовал за O(m*n), надеюсь вскоре получится реализовать за О(m+n)) Сергей, спасибо вам большое, особенно за курс по ООП)

  • @Yornero
    @Yornero 3 ปีที่แล้ว +2

    Классный алгоритм, прекрасный в своей простоте. Помню решал схожую задачу, но через хэширование

  • @ВалдосАрдуино
    @ВалдосАрдуино ปีที่แล้ว +2

    Очень круто объясняешь! Спасибо за уроки!

  • @rpuropu
    @rpuropu 3 ปีที่แล้ว +2

    гениальный алгоритм).. сигарета потухла давно) перематывал раз 20..)

  • @viktorzherekhin8590
    @viktorzherekhin8590 ปีที่แล้ว +1

    Для целей обучения полезно взять описание алгоритма и пытаться самому реализовать его на Пайтон. И потом проверить, чтобы получился одинаковый результат.
    Т.к. одно и то же можно реализовать по-разному. Тот же список, к примеру, можно заранее задать с конкретными элементами (нулями, к примеру), а можно формировать в процессе выполнения цикла (pi.append(0)).
    Можно сделать через цикл for, можно - через while, и т.д.

  • @Vlad1998996
    @Vlad1998996 3 ปีที่แล้ว +9

    Сложно, но гениально.

  • @kpacccavchik
    @kpacccavchik 3 ปีที่แล้ว +7

    ничего не понял, но так интересно, что поскорее хочется начать изучать )

  • @ЕрвандАгаджанян-в3к
    @ЕрвандАгаджанян-в3к 3 ปีที่แล้ว +1

    Вы просто Гений!! Спасибище!!!

  • @nikitabbrv5947
    @nikitabbrv5947 2 ปีที่แล้ว +3

    Хочется весь плейлист сразу в оперативку себе подгрузить)

    • @greentea2619
      @greentea2619 10 หลายเดือนก่อน

      лучше в жесткий будет конечно

  • @justyar5781
    @justyar5781 ปีที่แล้ว

    Как раз сейчас алгоритмы смотрю = ) Спасибо за материал!

  • @versus666jzx
    @versus666jzx 2 ปีที่แล้ว +2

    13:40 не совсем корректно звучит "пи от нуля" и т.д. в данном случае, тут же все таки индексы некоторого списка, а не функция) Огромное спасибо за труд, все очень доходчиво!

  • @Эмиль-х5ф
    @Эмиль-х5ф ปีที่แล้ว +1

    Спасибо за такое классное объяснение 🔥

  • @nullnull557
    @nullnull557 ปีที่แล้ว +6

    Почему-то момент j = p[j-1] никто не обсуждает, хотя именно к нему нужно уделить внимание в первую очередь. Не понятно как к нему пришли

    • @nullnull557
      @nullnull557 ปีที่แล้ว

      Если префикс не подошёл, тогда нужно ее длину уменьшить. Максимально эффективно брать длину максимального префикса для самого префикса.

  • @ИльясХасаханов
    @ИльясХасаханов ปีที่แล้ว +1

    Красиво) Спасибо Вам большое)

  • @michaelshulga5560
    @michaelshulga5560 3 ปีที่แล้ว +5

    за алгоритмы однозначно лайк

  • @pythonofsky4545
    @pythonofsky4545 ปีที่แล้ว +3

    Классно! Жаль, невелик список алгоритмов в плэйлисте.

  • @Mirte_Li
    @Mirte_Li หลายเดือนก่อน +1

    Спасибо, было полезно

  • @PBarb-l1r
    @PBarb-l1r 2 หลายเดือนก่อน +1

    а зачем рассматривать суффиксы с последним символом образца на 6:30 и далее? ведь если последний символ образца(допустим P_j) совпал с символом строки, то образец считается найденным. А если P_j не совпал, то важно максимальное совпадение префикса и суффикса в образце БЕЗ последнего символа для выполнения сдвига.
    В последнем случае, если я правильно понимаю, ещё может получиться равенство P_j следующей букве после полученного макс. префикса (т.е. сдвиг будет на ту же самую букву, которая уже точно известно, что не совпала).

  • @nemo917
    @nemo917 3 ปีที่แล้ว +1

    Большое спасибо за видео!

  • @hunya_k
    @hunya_k ปีที่แล้ว +1

    Спасибо, очень понятно!

  • @silentlyow
    @silentlyow 2 ปีที่แล้ว +1

    Еще можно на основе хэшей, посчитать хэш строки и хэш того что нужно найти и уже пройтись по строке и посмотреть есть ли одинаковые, сложность O(n)

  • @TheSadmint
    @TheSadmint 3 ปีที่แล้ว +6

    спасибо за видео!
    А регулярные выражения именно этот алгоритм используют?

  • @nitra-hl2fj
    @nitra-hl2fj 3 ปีที่แล้ว +4

    Видео хорошее, только непонятно: зачем вынесли последнее условие из цикла while? Образ "лилила" в конце строки "лилилось лилила" одновременно выдаст и "образ найден" и "образ не найден"

    • @selfedu_rus
      @selfedu_rus  3 ปีที่แล้ว +2

      Да, согласен, недосмотрел! Можно поправить вот так: if i == n and j != m: Условие вне цикла, чтобы не выполнять лишние операторы в теле цикла. Исправил программу на github.

  • @DDR4605
    @DDR4605 ปีที่แล้ว +1

    Посмотрел один раз, потом записал конспект, потом решил одну задачку со шпорой, смотрю второй раз. Начал что-то понимать…😮

  • @ankhmarcius8331
    @ankhmarcius8331 3 ปีที่แล้ว +2

    если уже смотрел алгоритм в питоне, то понимаешь что m=len(a), в видео же, не оговаривается о какой m идет разговор, и почему j=m

  • @АлександрШеремет-я7е
    @АлександрШеремет-я7е ปีที่แล้ว +2

    Так какой алгоритм лучше: КМП или БМХ ?

  • @wadahalgabri560
    @wadahalgabri560 2 ปีที่แล้ว +1

    Спасибо
    Очень помогло !

  • @СарматПересветов
    @СарматПересветов 4 หลายเดือนก่อน +1

    Интересный видос

  • @ВикторЖигурда
    @ВикторЖигурда 3 ปีที่แล้ว +5

    Хотелось бы по-больше инфы по алгоритмам

  • @НовиковИван-е8т
    @НовиковИван-е8т ปีที่แล้ว

    потрясающе

  • @user-wm3sb9gj7q
    @user-wm3sb9gj7q 2 ปีที่แล้ว +1

    спасибо огромное!

  • @slava_zxz
    @slava_zxz 9 หลายเดือนก่อน +1

    Спасибо

  • @RedkeiGost
    @RedkeiGost ปีที่แล้ว +2

    Только в английской Википедии и нагуглил упомянание, что Кнут в примечаниях работы "Selected Papers on Design of Algorithms" писал про Матиясевича. И больше ничего. Найти бы ещё какой-то материал, подробнее да убедительнее. Если он первый опубликовал, то где он опубликовал? В той же Википедии ссылка на Кнута и работу Матиясевича 1971 года.

    • @RedkeiGost
      @RedkeiGost 6 หลายเดือนก่อน

      @@deniskamal подробнее, это когда больше подробностей.

    • @RedkeiGost
      @RedkeiGost 6 หลายเดือนก่อน

      @@deniskamal которые убеждают. Очевидно же.

  • @ShadowStormlq5mwdasd
    @ShadowStormlq5mwdasd ปีที่แล้ว +1

    Интересно в чём и как Вы делаете ваши уроки?

  • @Slay-.-
    @Slay-.- 5 หลายเดือนก่อน +1

    какая сложность будет если решать через оператор in?

  • @bonie3044
    @bonie3044 3 ปีที่แล้ว +2

    я смотрел твой плейлист по flask
    как я тут оказался?

  • @plunk6774
    @plunk6774 2 ปีที่แล้ว +2

    Спасибо за ролик, очень понятно! А как вы учили алгоритмы?

  • @UrTa91
    @UrTa91 ปีที่แล้ว +1

    Ну пожалуйста можно в темном цвете делать презентация смотрю ночью мне пипец как ярко

  • @СергейФергюсон-ж7е
    @СергейФергюсон-ж7е ปีที่แล้ว +1

    Это где применяется ? В каких проектах ?

  • @ФЕДОРКУЛАВА
    @ФЕДОРКУЛАВА 2 ปีที่แล้ว

    не могу понять логику подсчета количества операций при пошаговом сравнении. если длина массива исходного массива n , а длина образа m , как мы получаем сложность n*m. При каждом сдвиге количеcтво операций равно m(длина образа), число сдвигов образа получим вычитанием длины образа из длины исходной строки, плюс один (n-m+1)*m. При данном примере получается 72+15=87. Максимальная сложность по видео равна 17*6=102, данную разницу вы игнорируете как не значительную? Или я не правильно считаю?

  • @1984Nik1
    @1984Nik1 3 ปีที่แล้ว +2

    супер

  • @alphonsecapone8218
    @alphonsecapone8218 3 ปีที่แล้ว +1

    Доброго времени суток) Прошу прощения и ни на что не претендую, просто учусь и стараюсь разобраться.
    Из того что я на данный момент понял про концепцию большого О - умножение подразумевает под собой вложенный цикл. А в прямом поиске его нет (по крайней мере в версии, которую я попробовал написать). И получается что его сложность в общем случае зависит только от размера источника поиска - О(n). Это может хоть как-то быть правильно?
    Просто я попробовал замерить скорости у этих алгоритмов и из кучи прогонов только раз смог добиться того чтобы КМП обогнал прямой и то только когда сделал для него все условия (красивые, для больших пропусков, повторения букв и всё такое).

    • @ambient_cocklushkin
      @ambient_cocklushkin 3 ปีที่แล้ว

      Концепция Big O подразумевает не в общем случае, а "в худшем случае", а при прямом поиске для каждой буквы строки в худшем случае придется проходится по каждой букве образца, отсюда и получается O(m*n)

  • @MrIgor989
    @MrIgor989 3 ปีที่แล้ว +1

    Ты гений

  • @ShadowStormlq5mwdasd
    @ShadowStormlq5mwdasd ปีที่แล้ว +1

    Этот алгоритм используется в python? Например в str.find() и всех похожим функциям? Кто знает?

    • @licantrop609
      @licantrop609 ปีที่แล้ว

      Скорее всего в str.__contains__() используется.

  • @ceo-s
    @ceo-s ปีที่แล้ว

    Подскажите пожалуйста, зачем всё таки брать п[ j-1 ] при формировании массива п если можно просто поставить 0. Префиксы то всё равно все сначала идут

    • @DDR4605
      @DDR4605 ปีที่แล้ว

      Это условие если j>0

  • @andreiviltouski2390
    @andreiviltouski2390 3 ปีที่แล้ว +2

    👍

  • @MrJannes
    @MrJannes 3 ปีที่แล้ว

    Мы префикс функцию используем только один раз или после каждого при "прикладывания" образца к тексту?

    • @selfedu_rus
      @selfedu_rus  3 ปีที่แล้ว

      префиксы формируются на 1-м этапе до поиска образца, затем, на 2-м этапе при несовпадении символов используется сдвиг на вычисленный префикс на 1-м этапе

  • @riplock77
    @riplock77 3 ปีที่แล้ว

    Сдравстуйте, подскажите пожалуйста как сделать чтобы при запуске PyCharm запускалось главное меню с проектами а не запускался последний проект 🙏

    • @doloidiktatorov
      @doloidiktatorov 3 ปีที่แล้ว +3

      File
      Settings
      Appearance & Behavior
      System Settings
      Startup/Shoutdown
      Reopen last project

  • @dvd6307
    @dvd6307 3 ปีที่แล้ว +5

    Да ты серьезно? Я не успел ещё посмотреть остальные плейлисты, а тут новое. Круто конечно, но... Что мне делать?

    • @viktorkomlev5804
      @viktorkomlev5804 3 ปีที่แล้ว +8

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

  • @КатяВегера-м5у
    @КатяВегера-м5у 11 หลายเดือนก่อน +1

    Скажите пожалуйста в какой программе пишите код

    • @selfedu_rus
      @selfedu_rus  11 หลายเดือนก่อน +1

      PyCharm

  • @sainco3036
    @sainco3036 3 ปีที่แล้ว +3

    Жаль, django закончилось, я только вошел во вкус)

  • @dazdess
    @dazdess 3 ปีที่แล้ว

    А можно ли тут обойтись регулярными выражениями? Насколько этот алгоритм будет быстрее работать чем регулярные выражения?

    • @selfedu_rus
      @selfedu_rus  3 ปีที่แล้ว

      Если просто найти образец в строке, то подобные алгоритмы будут работать быстрее регулярок. (При условии, что программа делается на С++, а не Python). Если же используете Python, то опять же, лучше брать соответствующие методы строк: count(), index(), find() и т.п. Регулярные - это более изощренный инструмент для тонкой обработки.

  • @АртиКалмыков
    @АртиКалмыков 2 ปีที่แล้ว

    Регулярные выражения?

  • @janibektursynbaev
    @janibektursynbaev 3 ปีที่แล้ว +1

    пишет не найдено

  • @begula_chan
    @begula_chan 2 ปีที่แล้ว +1

    Можно регулярным выражением сделать

  • @АлеМммиии
    @АлеМммиии 7 หลายเดือนก่อน +2

    А я ничего не поняла

  • @owenearmusic
    @owenearmusic 3 ปีที่แล้ว

    Мое лицо когда пытаюсь осознать этот алгоритм 6:42

  • @tenelokis
    @tenelokis 2 ปีที่แล้ว +1

    Полчаса пролетели за минуту 🙂

  • @СтепСтеп-п1л
    @СтепСтеп-п1л 2 ปีที่แล้ว

    интересно почему этот вариант не работает
    h1 = "ллилилась лилилось"
    h2 = "лилилась"
    a=0
    b=1
    c=2
    d=3
    e=4
    f=5
    g=6
    k=7
    l=8
    for i in range(len(h1)-len(h2)-1):
    uo = h1[a]+h1[b]+h1[c]+h1[d]+h1[e]+h1[f]+h1[g]+h1[k]+h1[l]
    if h2 == uo:
    print('gotovo')
    a = a + 1
    b = b + 1
    c = c + 1
    d = d + 1
    e = e + 1
    f = f + 1
    g = g + 1
    k = k + 1
    l = l + 1

    • @whitepepper742
      @whitepepper742 ปีที่แล้ว

      а в чем логика здесь вообще? зачем мы каждой отдельной буквой обозначаем номер буквы образца? Зачем здесь инициализация uo, если оно используется один раз?
      Ну и главный вопрос, если образец будет из, допустим, 99 букв, вы будете каждый номер буквы образца инициализировать отдельно? зачем нам 99 переменных?
      Ничего не понятно. И читаемость кода ужасная

  • @RocetDev
    @RocetDev 3 ปีที่แล้ว +2

    Привет друг. Я тебе рекомендую сделать свой курс на stepik что бы прибавить аудиторию

    • @selfedu_rus
      @selfedu_rus  3 ปีที่แล้ว

      Спасибо, в ближайших планах )

  • @искандерфайзуллоев-ф4я
    @искандерфайзуллоев-ф4я ปีที่แล้ว +3

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

  • @ibragimov-s3y
    @ibragimov-s3y 3 ปีที่แล้ว +3

    Давай джанго , плиз

  • @stas-web
    @stas-web 2 ปีที่แล้ว +1

    Реализация на JS:
    function kmp(text, str) {
    const N = text.length, M = str.length;
    let p = new Uint16Array(str.length);
    for (i = 1, j = 0; i < M; i++) {
    while (j > 0 && str[j] != str[i]) j = p[j-1];
    if(str[j] == str[i]) j++;
    p[i] = j;
    }
    for (i = 0, j = 0; i < N; i++) {
    while (j > 0 && str[j] != text[i]) j = p[j - 1];
    if (str[j] == text[i]) j++;
    if (j == M) return i - j + 1;
    }
    return -1;
    }
    console.log(kmp('лилилось лилилась', 'лилила')); // 9

  • @maiorchiks3107
    @maiorchiks3107 2 ปีที่แล้ว

    ничего не понял (((

  • @janibektursynbaev
    @janibektursynbaev 3 ปีที่แล้ว

    в чем тут ошибка?
    #include
    using namespace std;
    string find(string s, string a, vector pi){
    int i = 0;
    int j = 0;
    while(i

  • @lubovd5335
    @lubovd5335 3 ปีที่แล้ว +1

    Матиясевич Советский ученый, а не русский

    • @selfedu_rus
      @selfedu_rus  3 ปีที่แล้ว +3

      Русскую национальность никто не отменял, см. в википедии: ru.wikipedia.org/wiki/Матиясевич,_Юрий_Владимирович

  • @ЛистокЯблони-р1у
    @ЛистокЯблони-р1у 3 ปีที่แล้ว +3

    Python - это хорошо, но JS ещё лучше)

    • @fghinty7623
      @fghinty7623 3 ปีที่แล้ว +4

      а?

    • @nadyamoscow2461
      @nadyamoscow2461 3 ปีที่แล้ว +4

      JS тут тоже есть. Правда, не знаю, чем оно лучше, чем Python

    • @whitepepper742
      @whitepepper742 ปีที่แล้ว

      Опять гонки какой язык лучше🤡Под определенную задачу свой язык

  • @котбегемот-ъ7с
    @котбегемот-ъ7с ปีที่แล้ว

    А если сравнивать текст с образцом по букве а и в случае совпадения сравнивать всё?

  • @Poligonchik
    @Poligonchik 3 หลายเดือนก่อน

    Супер понятно, спасибо!