#2. Алгоритм Бойера-Мура-Хорспула | Алгоритмы на Python

Поделиться
HTML-код
  • Опубликовано: 2 дек 2024

Комментарии • 58

  • @Bah1918
    @Bah1918 3 года назад +21

    Вы не перестаёте удивлять . СПАСИБО

  • @vladimirfolomeev5697
    @vladimirfolomeev5697 3 года назад +8

    Спасибо за знания, Ваш канал просто находка для становления специалиста.

  • @sekastrashes
    @sekastrashes Год назад +1

    спасибо за видео. Мало таких полезных каналов как ваш

  • @ЕрвандАгаджанян-в3к
    @ЕрвандАгаджанян-в3к 2 года назад +2

    Урок просто нереальный! Спасибо!

  • @qqgl-x6p
    @qqgl-x6p 6 месяцев назад +1

    люблю вас, вы растите олимпиадников

  • @АделяМахиянова-е1ч

    спасибо большое, вы спасли меня от ошибок на сессии

  • @thegreatpresto
    @thegreatpresto 3 года назад +2

    Вас очень приятно слушать

  • @friend1cat
    @friend1cat 3 года назад +7

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

  • @ЕлизаветаАлферова-э2д

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

  • @СарматПересветов
    @СарматПересветов 3 месяца назад +1

    Большое спасибо)

  • @neponiatniichell9508
    @neponiatniichell9508 Год назад +2

    Если я не ошибаюсь, то это лучший алгоритм поиска нужной строки в тексте

  • @yurik-r5l
    @yurik-r5l Год назад

    Спасибо за Ваши уроки! Но, либо я что-то не могу понять, либо здесь неточность. На 6:20 Вы говорите, что при несовпадении не последних символов в образе и строке, смещение выбирается по не совпавшему символу образа. Мне кажется более правильно будет так. В этом случае смещение выбирается по символу СТРОКИ, соответствующему последнему символу образа.

  • @fghinty7623
    @fghinty7623 3 года назад +8

    круто!

  • @TRVQ2
    @TRVQ2 2 года назад +3

    Можно просто как-то так, к примеру:
    def find_bmh_my(text, pattern):
    if (len_pattern := len(pattern)) > (len_text := len(text)):
    return -1
    shifts = {}
    for i, v in enumerate(pattern):
    if v not in shifts:
    shifts[v] = i + 1
    shift = (len_pattern_minus_one := len_pattern - 1)
    while shift < len_text:
    p, t = len_pattern_minus_one, shift
    while p >= 0 and text[t] == pattern[p]:
    p, t = p-1, t-1
    if p == -1:
    return t + 1
    shift += shifts.get(text[shift], len_pattern)
    return -1

  • @sainco3036
    @sainco3036 3 года назад +2

    Спасибо.

  • @luckytima2315
    @luckytima2315 3 года назад +2

    Спасибо большое ))) Только не бросайте Django :(

  • @ВиталийКенарь
    @ВиталийКенарь 2 года назад +1

    спасибо)

  • @АлександрШеремет-я7е

    Если несовпадающий символ не самый правый/последний в образе то смещение берем по:
    1. У вас: по несовпадающему символу образа
    2. Вот тут: ruclips.net/video/KIUHWMwavQg/видео.html по последнему символу образа
    3. А вот тут ruclips.net/video/N6G6HVwJ4wQ/видео.html : по несовпадающему символу СТРОКИ
    Почему такие разночтения ?

    • @0ver4ance
      @0ver4ance Год назад

      Потому что автор основную идею алгоритма не объяснил. Суть идеи в том, что у нас есть "стоп-символ". Это тот символ, который стоит в тексте под последним символом шаблона. В этом случае:
      больше метеоданные
      данные
      стоп-символ буква "и".
      А в этом случае:
      большие метеданные
      данные
      уже буква "о".
      То есть после каждого смещения шаблона стоп-символ меняется.
      И основная идея алгоритма в том, чтобы в случае, если у нас происходит несоответствие символов в месте, то нам нужно подогнать под стоп-символ последнее вхождение стоп-символа в шаблоне если он есть в шаблоне, если его нет то просто сместить шаблон на всю его длину. Но может возникнуть тогда проблема, что если у нас стоп-символ есть в шаблоне и он находится именно в последней позиции шаблона в единственном экземпляре, то тогда возникнет вечный цикл. Это соответствует следующей ситуации:
      больше метеоданные
      данные
      В этом случае мы просто двигаем шаблон на всю его длину.
      Вот и вся идея, которую можно реализовать по-разному, поэтому у авторов, которые рассказывают конкретные реализации, но при этом не рассказывают саму идею алгоритма и возникают такие вопросы

  • @Иван-х8ж2ф
    @Иван-х8ж2ф Год назад +1

    Здравствуйте.
    Почему в программе, при формировании таблицы смещений, когда формируем последний символ, не учитывается то, что этот последний символ может совпадать с другим символом из образа? Как в образе "зорро", например.

    • @god_of_cringe
      @god_of_cringe Год назад +2

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

  • @DreamBetterMe
    @DreamBetterMe 3 года назад +21

    a = input('Пишите строка: ')
    b = input('Пишите элемент которые вы хотите найти индекс: ')
    if len(b) > len(a):
    print('Такой элемент нет в строке!!!')
    else:
    x = []
    for i in range(len(a)):
    if a[i:len(b)+i] == b:
    x.append(i)
    if len(x) == 0:
    print('Такой элемент нет в строке!!!')
    else:
    print('В строке есть ', len(x), ' элемент. Индекс: ', x)
    Я разработал собственный алгоритм может этот алгоритм раньше была. Но я разработал его собственный головой. Этот алгоритм найдёт все элементы которые надо найти в строке. Пожалуйста памагите проверить правильность этого алгоритма

    • @hamzarahatbekov4536
      @hamzarahatbekov4536 3 года назад +3

      +?

    • @bektursunkabylov1883
      @bektursunkabylov1883 3 года назад +1

      +?

    • @kan4317
      @kan4317 3 года назад +1

      Str.find()
      Или
      element in string - возвращает булево значение

    • @maksdemkovych8884
      @maksdemkovych8884 2 года назад +1

      @@hamzarahatbekov4536сложность большая , автор в начале видео говорил об этом

    • @pilina_
      @pilina_ 2 года назад

      спасибо, ваш код мне более понятен!

  • @_SkyDancer
    @_SkyDancer 6 месяцев назад +1

    А как искать в обратную сторону с конца строки и до начала этим алгоритмом можно?

    • @НикитаХлобыстов-г2й
      @НикитаХлобыстов-г2й 6 месяцев назад

      ну можешь переверунть строку и образ сразу после их объявления)
      а результат (если образ есть в строке) переобъяви >>> результат = длинна строки - 1 - результат

  • @exe88cution
    @exe88cution 3 года назад +2

    Я так понимаю, этот алгоритм быстрее и проще предыдущего в этом плейлисте?

    • @selfedu_rus
      @selfedu_rus  3 года назад +2

      Скорее, он просто другой. Реализуется проще, но по скорости в зависимости от данных.

    • @exe88cution
      @exe88cution 3 года назад +1

      @@selfedu_rus спасибо за ответ)

  • @artyomspb6820
    @artyomspb6820 3 года назад +2

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

    • @selfedu_rus
      @selfedu_rus  3 года назад +1

      Обновил программу, возможно это было из-за отсутствия переменной j в области видимости цикла while. Если будут проблемы, укажите строку и образ, для которых запускаете алгоритм.

  • @shalnayalala
    @shalnayalala 3 года назад +3

    Программа выдает неправильный индекс (5), если искать образ "kasha" в строке "dasha dasha kasha" :(

    • @selfedu_rus
      @selfedu_rus  3 года назад +3

      Да, была ошибочка в программе (если несовпадение для первого символа, то j=0 и делался вывод, что образ найден). Поправил, выложил на github измененный вариант. Скачивайте и наслаждайтесь! )) Спасибо!

  • @rpuropu
    @rpuropu 3 года назад +2

    Вы ещё и за патчами питона успеваете следить).. ф-строки увидел) материал старый, а код современный)

  • @gleck8212
    @gleck8212 Год назад

    А если в образе будет символ `*` ?) Боюсь, что тогда программа полетит)

    • @gleck8212
      @gleck8212 Год назад

      Если тут есть кто на с++ и кому нужен код этого алгоритма, то вот он:
      ```
      namespace Bower_Moore {
      typedef struct {
      std::unordered_map table;
      size_t other_chars;
      } offset_table;
      size_t get_size_str(char* str) {
      size_t size = 0;
      while (str[size]) {
      size++;
      }
      return size;
      }
      bool contains(offset_table* table, char key) {
      return table->table.find(key) != table->table.end();
      }
      offset_table create_table(char* image) {
      offset_table table;
      size_t size_image = get_size_str(image);
      for (size_t i = size_image - 2, j = 1; (int)i >= 0; i--, j++) {
      if (!contains(&table, image[i])) {
      table.table[image[i]] = j;
      }
      }
      if (!contains(&table, image[size_image - 1])) {
      table.table[image[size_image - 1]] = size_image;
      }
      table.other_chars = size_image;
      return table;
      }
      int find(char* str, char* substr) {
      offset_table templ = create_table(substr);
      size_t size_str = get_size_str(str);
      size_t size_substr = templ.other_chars;
      if (size_str >= size_substr) {
      size_t i = size_substr - 1;
      while (i < size_str) {
      size_t j;
      size_t k = 0;
      bool flag = false;
      for (j = size_substr - 1; (int)j >= 0; j--) {
      if (str[i - k] != substr[j]) {
      size_t off;
      if (j == size_substr - 1) {
      off = (contains(&templ, str[i])) ? templ.table[str[i]] : templ.other_chars;
      } else {
      off = templ.table[substr[j]];
      }
      i += off;
      flag = true;
      break;
      }
      k++;
      }
      if (!flag) {
      return i - k + 1;
      }
      }
      }
      return -1;
      }
      }
      ```

    • @hanmahanma5067
      @hanmahanma5067 7 месяцев назад

      Пхахаха попробовал так и вышло

  • @tedarcher9120
    @tedarcher9120 3 года назад

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

    • @selfedu_rus
      @selfedu_rus  3 года назад

      Все верно, здесь только первое. Немного фантазии, поменять код и все у вас получится!

    • @OneOfWun-n2g
      @OneOfWun-n2g 3 года назад

      у тебя получилось? если да, то подскажи пожалуйста

    • @sDerrnit18
      @sDerrnit18 2 года назад

      ​@@OneOfWun-n2g Если первый индекс вхождения - 5, то ты уже проверил первые 5 элементов на вхождение подстроки. Теперь осталось проверить оставшуюся строку на вхождение. Т.е. строку начиная с индекса 5+1 до n.

    • @mrmccoy8812
      @mrmccoy8812 2 года назад

      @@sDerrnit18 если такимспособом попытаться найти 'xxx' в 'xxxx', то такой подход работает неправильно

  • @lauhG3
    @lauhG3 3 года назад

    а почему в 9 строке не :
    for i in range(M[-2], -1, 1):
    ?? мы же с индексами работаем чи шо я прост новичок )

  • @ankhmarcius8331
    @ankhmarcius8331 3 года назад +3

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

    • @ssyucfa
      @ssyucfa 3 года назад

      со 2 раза все очевидно)

  • @АртемАрте-г5х
    @АртемАрте-г5х 2 года назад +5

    когда я увидел код, то глаза закровоточили....

    • @aiat122
      @aiat122 9 месяцев назад

      почему?

    • @only_girlz
      @only_girlz 3 месяца назад

      почему?

    • @32prince
      @32prince 3 месяца назад

      ​@@only_girlz он нулевый еще

  • @vladimirdymshakov8393
    @vladimirdymshakov8393 2 года назад +1

    К сожалению, похоже на фокус - кролик из рукава. Ни одно утверждение не доказано, как и не доказана и работоспособность алгоритма.

    • @JonhSliver
      @JonhSliver 2 года назад

      ты что дебил камрад ?
      забудь вообще про программирование, твое - это дворы подметать, купи себе метелку в Леруа за 50 рублей

    • @vladimirdymshakov8393
      @vladimirdymshakov8393 2 года назад

      @@JonhSliver Болеете? Хотел бы пожелать скорейшего выздоровления, но не рискну ввиду тяжелого состояния пациента.

  • @котбегемот-ъ7с
    @котбегемот-ъ7с Год назад

    Здесь алгоритм должен быть по букве ы потому как она редкая