mirror of
https://github.com/krahets/hello-algo.git
synced 2026-07-11 06:56:06 +00:00
Review the ru version with Codex. (#1870)
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
# Задача о расстоянии редактирования
|
||||
|
||||
Расстояние редактирования, также называемое расстоянием Левенштейна, обозначает минимальное число правок, необходимых для взаимного преобразования двух строк. Обычно оно используется для измерения сходства двух последовательностей в информационном поиске и обработке естественного языка.
|
||||
Расстояние редактирования, также называемое расстоянием Левенштейна, - это минимальное количество изменений, необходимых для преобразования одной строки в другую. Обычно оно используется для измерения сходства двух последовательностей в информационном поиске и обработке естественного языка.
|
||||
|
||||
!!! question
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||

|
||||
|
||||
**Задачу о расстоянии редактирования можно очень естественно описать через модель дерева решений**. Строки соответствуют узлам дерева, а один раунд решения (одна операция редактирования) соответствует одному ребру дерева.
|
||||
**Задачу о расстоянии редактирования можно естественным образом объяснить с помощью модели дерева решений**. Строки соответствуют узлам дерева, а один шаг решения, то есть одна операция редактирования, соответствует одному ребру дерева.
|
||||
|
||||
Как показано на рисунке ниже, если не ограничивать число операций, то каждый узел может порождать множество ребер, и каждое из них соответствует одному из вариантов преобразования. Это означает, что преобразовать `hello` в `algo` можно множеством разных путей.
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
- Если $s[n-1]$ и $t[m-1]$ совпадают, их можно просто пропустить и сразу перейти к сравнению $s[n-2]$ и $t[m-2]$ .
|
||||
- Если $s[n-1]$ и $t[m-1]$ различны, нужно выполнить над $s$ одну операцию редактирования (вставку, удаление или замену), чтобы последние символы стали одинаковыми, после чего можно перейти к задаче меньшего размера.
|
||||
|
||||
Иначе говоря, каждое решение (операция редактирования), которое мы выполняем над строкой $s$ , меняет те символы, которые еще остаются несопоставленными в строках $s$ и $t$ . Поэтому состояние определяется текущими позициями рассматриваемых символов в $s$ и $t$ , то есть состоянием $[i, j]$ .
|
||||
Иначе говоря, каждый шаг решения, то есть операция редактирования над строкой $s$ , меняет те символы, которые еще необходимо сопоставить в строках $s$ и $t$ . Поэтому состояние определяется текущими позициями рассматриваемых символов в $s$ и $t$ , то есть состоянием $[i, j]$ .
|
||||
|
||||
Подзадача, соответствующая состоянию $[i, j]$ , такова: **минимальное число операций редактирования, необходимое для преобразования первых $i$ символов строки $s$ в первые $j$ символов строки $t$**.
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
|
||||

|
||||
|
||||
Согласно этому анализу оптимальная подструктура такова: минимальное число шагов редактирования для $dp[i, j]$ равно минимуму из трех значений - $dp[i, j-1]$ , $dp[i-1, j]$ и $dp[i-1, j-1]$ - плюс цена текущей операции редактирования $1$ . Значит, уравнение перехода состояния имеет вид:
|
||||
Согласно этому анализу оптимальная подструктура такова: минимальное число шагов редактирования для $dp[i, j]$ равно минимуму из трех значений - $dp[i, j-1]$ , $dp[i-1, j]$ и $dp[i-1, j-1]$ - плюс $1$ шаг за текущее редактирование. Значит, уравнение перехода состояния имеет вид:
|
||||
|
||||
$$
|
||||
dp[i, j] = \min(dp[i, j-1], dp[i-1, j], dp[i-1, j-1]) + 1
|
||||
@@ -71,7 +71,7 @@ $$
|
||||
[file]{edit_distance}-[class]{}-[func]{edit_distance_dp}
|
||||
```
|
||||
|
||||
Как показано на рисунке ниже, процесс переходов состояния в задаче о расстоянии редактирования очень похож на процесс в задачах о рюкзаке: в обоих случаях это заполнение двумерной сетки.
|
||||
Как показано на рисунке ниже, процесс переходов состояния в задаче о расстоянии редактирования очень похож на задачи о рюкзаке: и там и здесь его можно рассматривать как заполнение двумерной сетки.
|
||||
|
||||
=== "<1>"
|
||||

|
||||
@@ -122,7 +122,7 @@ $$
|
||||
|
||||
Поскольку $dp[i,j]$ зависит от значения сверху $dp[i-1, j]$ , слева $dp[i, j-1]$ и слева сверху $dp[i-1, j-1]$ , прямой обход после оптимизации памяти теряет значение слева сверху, а обратный обход не позволяет заранее построить значение слева $dp[i, j-1]$ . Значит, оба наивных варианта обхода здесь непригодны.
|
||||
|
||||
Чтобы решить эту проблему, можно использовать переменную `leftup` для временного сохранения значения слева сверху $dp[i-1, j-1]$ ; после этого остается учитывать только верхнее и левое значения. Тогда ситуация становится эквивалентной задаче о полном рюкзаке, и можно выполнять прямой обход. Код приведен ниже:
|
||||
Чтобы решить эту проблему, можно использовать переменную `leftup` для временного сохранения значения слева сверху $dp[i-1, j-1]$ ; после этого остается учитывать только верхнее и левое значения. Тогда ситуация становится аналогичной задаче о полном рюкзаке, и можно выполнять прямой обход. Код приведен ниже:
|
||||
|
||||
```src
|
||||
[file]{edit_distance}-[class]{}-[func]{edit_distance_dp_comp}
|
||||
|
||||
Reference in New Issue
Block a user