Освоение сопоставления строк: полное руководство по CSES

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

  1. Метод грубой силы:
    Самый простой подход — последовательное сравнение каждого символа шаблона с каждым символом текста. Этот метод интуитивно понятен, но может быть неэффективен для больших текстов.

    def brute_force(text, pattern):
       n = len(text)
       m = len(pattern)
       for i in range(n - m + 1):
           j = 0
           while j < m and text[i + j] == pattern[j]:
               j += 1
           if j == m:
               return i
       return -1
  2. Алгоритм Кнута-Морриса-Пратта (KMP):
    Алгоритм KMP повышает эффективность за счет использования информации из предыдущих сравнений, чтобы избежать ненужных сравнений символов.

    def compute_lps(pattern):
       m = len(pattern)
       lps = [0] * m
       length = 0
       i = 1
       while i < m:
           if pattern[i] == pattern[length]:
               length += 1
               lps[i] = length
               i += 1
           else:
               if length != 0:
                   length = lps[length - 1]
               else:
                   lps[i] = 0
                   i += 1
    def kmp(text, pattern):
       n = len(text)
       m = len(pattern)
       lps = compute_lps(pattern)
       i = j = 0
       while i < n:
           if pattern[j] == text[i]:
               i += 1
               j += 1
               if j == m:
                   return i - j
           else:
               if j != 0:
                   j = lps[j - 1]
               else:
                   i += 1
       return -1
  3. Алгоритм Рабина-Карпа.
    Алгоритм Рабина-Карпа использует хеширование для эффективного поиска шаблона в тексте. Он использует скользящую хеш-функцию для обновления хэш-значений во время каждого сравнения.

    def rabin_karp(text, pattern):
       n = len(text)
       m = len(pattern)
       d = 256  # Number of characters in the input alphabet
       q = 101  # A prime number
       def compute_hash(string):
           hash_value = 0
           for char in string:
               hash_value = (hash_value * d + ord(char)) % q
           return hash_value
       pattern_hash = compute_hash(pattern)
       text_hash = compute_hash(text[:m])
       for i in range(n - m + 1):
           if pattern_hash == text_hash:
               if text[i:i + m] == pattern:
                   return i
           if i < n - m:
               text_hash = (d * (text_hash - ord(text[i]) * pow(d, m - 1, q)) + ord(text[i + m])) % q
       return -1
  4. Алгоритм Бойера-Мура.
    Алгоритм Бойера-Мура сканирует шаблон справа налево, пропуская сравнения, когда это возможно, на основе заранее вычисленного правила плохих символов и правила хорошего суффикса.

    def boyer_moore(text, pattern):
       n = len(text)
       m = len(pattern)
       bad_char = {}
       for i in range(m):
           bad_char[pattern[i]] = i
       def find_suffix(pattern):
           m = len(pattern)
           suffix = [0] * m
           suffix[m - 1] = m
           g = m - 1
           f = 0
           for i in range(m - 2, -1, -1):
               if i > g and suffix[i + m - 1 - f] < i - g:
                   suffix[i] = suffix[i + m - 1 - f]
               else:
                   if i < g:
                       g = i
                   f = i
                   while g >= 0 and pattern[g] == pattern[g + m - 1 - f]:
                       g -= 1
                   suffix[i] = f - g
           return suffix
       suffix = find_suffix(pattern)
       i = j = 0
       while i <= n - m:
           j = m - 1
           while j >= 0 and pattern[j] == text[i + j]:
               j -= 1
           if j < 0:
              return i
           else:
               char = text[i + j]
               if char in bad_char:
                   i += max(1, j - bad_char[char])
               else:
                   i += j + 1
       return -1

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

В заключение, умение сопоставлять строки имеет важное значение для эффективной обработки текста. Понимая и применяя различные алгоритмы, такие как метод грубой силы, алгоритм KMP, алгоритм Рабина-Карпа и алгоритм Бойера-Мура, вы сможете эффективно решать задачи поиска шаблонов.

Итак, продолжайте совершенствовать свои навыки сопоставления строк с помощью CSES! Приятного кодирования!