Чтение онлайн

на главную

Жанры

Фундаментальные алгоритмы и структуры данных в Delphi

Бакнелл Джулиан М.

Шрифт:

Применив обе версии (итеративную и рекурсивную), я сгенерировал матрицу для вычисления LCS слов "illiteracy" и "innumeracy". (Длина LCS этих слов равна 6 и выглядит как "ieracy".) Результаты этих немалых трудов приведены в таблицах 12.2 и 12.3. При использовании рекурсивной версии многие ячейки вообще не вычисляются (они помечены знаком вопроса). Эти ячейки образуют часть заключительной LCS.

Таблица 12.2. Итеративная матрица LCS слов "illiteracy" и "innumeracy".

Таблица 12.3.

Рекурсивная матрица LCS слов "illiteracy" и "innumeracy".

Итак, мы получили матрицу, которая определяет наиболее длинную общую подпоследовательность. Как ее можно использовать? Одна возможность связана с реализацией подпрограммы, которая создает текстовый файл, описывающий изменения, называемые последовательностью редактирования (edit sequence). Это может упростить создание аналогичной подпрограммы для текстового файла - что, собственно, является конечной целью данного раздела.

Код реализации простой технологии обхода, которая может быть приведена в соответствие с нашими потребностями, показан в листинге 12.26. Подпрограмма содержит два метода: первый вызывается пользователем с указанием имени файла, а второй представляет собой рекурсивную подпрограмму, которая записывает данные в файл. Весь основной объем работы выполняется во второй подпрограмме. Поскольку в матрице путь LCS кодируется в обратном направлении (т.е. для определения пути необходимо начать с конца и продвигаться к началу матрицы), мы создаем метод, который вначале вызывает сам себя, а затем записывает данные, соответствующие текущей позиции. Необходимо обеспечить прерывание выполнения рекурсивной подпрограммы. Это соответствует случаю, когда подпрограмма вызывается для ячейки (0,0). В этом случае никакие данные не записываются в файл. Если индекс строки То равен нулю, мы выполняем рекурсивный вызов, перемещаясь вверх по матрице (индекс строки From уменьшается), и предпринимаемым действием должно быть удаление символа из строки From. Если индекс строки From равен нулю, мы выполняем рекурсивный вызов, перемещаясь по матрице влево, и тогда действием является ставка текущего символа в строку То. И, наконец, если оба индекса не равны нулю, мы находим соответствующую ячейку в матрице, выполняем рекурсивный вызов и записываем действие в файл. Перемещению вниз соответствует удаление, перемещению вправо - вставка, перемещению по диагонали - ни одно из упомянутых действий (символ "переносится" из одной строки в другую). Для обозначения удаления мы будем использовать стрелку, указывающую вправо (-> ), а для обозначения вставки - стрелку, указывающую влево (<-). Перенос символа не обозначается.

Листинг 12.26. Вывод последовательности редактирования

procedure TtdStringLCS.slWriteChange(var F : System.Text;

aFromInx, aToInx : integer);

var

Cell : PtdLCSData;

begin

{если оба индекса равны нулю, данная ячейка является первой ячейкой матрицы LCS, поэтому подпрограмма просто выполняет выход}

if (aFromInx = 0) and (aToInx = 0) then

Exit;

{если индекс строки From равен нулю, ячейка расположена в левом столбце матрицы, поэтому необходимо переместиться вверх; этому будет соответствовать удаление}

if (aFromInx = 0) then begin

slWriteChange(F, aFromInx, aToInx-1);

writeln(F, '->', FToStr[aToInx]);

end

{если

индекс строки To равен нулю, ячейка расположена в верхней строке матрицы, поэтому необходимо переместиться влево; этому будет соответствовать вставка}

else

if (aToInx = 0) then begin

slWriteChange(F, aFromInx-1, aToInx);

writeln(F, '< - FFromStr[aFromInx]);

end

{в противном случае необходимо выполнить действия, указанные ячейкой}

else begin

Cell := FMatrix[aFromInx, aToInx];

case Cell^.ldPrev of

ldNorth : begin

slWriteChange(F, aFromInx-1, aToInx);

writeln(F, ' <- ', FFromStr[aFromInx]);

end;

ldNorthWest : begin

slWriteChange(F, aFromInx-1, aToInx-1);

writeln(F, ' ', FFromStr[aFromInx]);

end;

ldWest : begin

slWriteChange(F, aFromInx, aToInx-1);

writeln(F, '-> FToStr[aToInx]);

end;

end;

end;

end;

procedure TtdStringLCS.WriteChanges(const aFileName : string);

var

F : System.Text;

begin

System.Assign(F, aFileName);

System.Rewrite(F);

try

slWriteChange(F, length(FFromStr), length(FToStr));

finally

System.Close(F);

end;

end;

Ниже показан текстовый файл, который был сгенерирован для преобразования слова "illiteracy" в слово "innumeracy".

< - i

<- l

<- l

i

<- t

– > n

– > n

– > u

– > m

e

r

a

с

y

Это представление действий по редактированию легко доступно для понимания, но при необходимости его можно развернуть. Как видите, наиболее длинная общая подпоследовательностью является (i, e, r, a, c, y), а определение удалений и вставок не представляет сложности.

Памятуя о том, что примененный метод является рекурсивным, следует подумать о требуемой для его реализации глубине стека. Если бы строки вообще не имели общих символов, последовательность редактирования сводилась бы к удалению всех символов первой строки и вставке всех символов второй строки. Если первая строка содержит n символов, а вторая m, глубина стека должна быть пропорциональной сумме n + m.

Вычисление LCS двух файлов

После того, как мы ознакомились с решением для двух строк, его можно модифицировать для вычисления LCS и генерации команд редактирования для двух текстовых файлов. Дабы упростить себе задачу, выполним считывание обоих файлов в объект TStringsLists. Понятно, что теперь одновременно выполняется сравнение целых текстовых строк, а не символов, тем не менее, в основном, реализация остается практически той же самой. Код интерфейса и вспомогательных методов приведен в листинге 12.27.

Листинг 12.27. Класс TtdFileLCS

type

TtdFileLCS = class private

FFromFile : TStringList;

FMatrix : TtdLCSMatrix;

FToFile : TStringList;

protected

function slGetCell(aFromInx, aToInx : integer): integer;

procedure slWriteChange(var F : System.Text;

aFromInx, aToInx : integer);

public

constructor Create(const aFromFile, aToFile : string);

destructor Destroy; override;

Поделиться:
Популярные книги

На границе тучи ходят хмуро...

Кулаков Алексей Иванович
1. Александр Агренев
Фантастика:
альтернативная история
9.28
рейтинг книги
На границе тучи ходят хмуро...

Кодекс Охотника. Книга III

Винокуров Юрий
3. Кодекс Охотника
Фантастика:
фэнтези
попаданцы
аниме
7.00
рейтинг книги
Кодекс Охотника. Книга III

Последний попаданец 11. Финал. Часть 1

Зубов Константин
11. Последний попаданец
Фантастика:
фэнтези
юмористическое фэнтези
рпг
5.00
рейтинг книги
Последний попаданец 11. Финал. Часть 1

Книга пяти колец

Зайцев Константин
1. Книга пяти колец
Фантастика:
фэнтези
6.00
рейтинг книги
Книга пяти колец

Поступь Империи

Ланцов Михаил Алексеевич
7. Сын Петра
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Поступь Империи

Купидон с топором

Юнина Наталья
Любовные романы:
современные любовные романы
7.67
рейтинг книги
Купидон с топором

Наследник в Зеркальной Маске

Тарс Элиан
8. Десять Принцев Российской Империи
Фантастика:
городское фэнтези
попаданцы
аниме
5.00
рейтинг книги
Наследник в Зеркальной Маске

Совок 5

Агарев Вадим
5. Совок
Фантастика:
детективная фантастика
попаданцы
альтернативная история
6.20
рейтинг книги
Совок 5

Аномальный наследник. Том 1 и Том 2

Тарс Элиан
1. Аномальный наследник
Фантастика:
боевая фантастика
альтернативная история
8.50
рейтинг книги
Аномальный наследник. Том 1 и Том 2

Теневой путь. Шаг в тень

Мазуров Дмитрий
1. Теневой путь
Фантастика:
фэнтези
6.71
рейтинг книги
Теневой путь. Шаг в тень

Попаданка в академии драконов 2

Свадьбина Любовь
2. Попаданка в академии драконов
Любовные романы:
любовно-фантастические романы
6.95
рейтинг книги
Попаданка в академии драконов 2

Гром над Империей. Часть 2

Машуков Тимур
6. Гром над миром
Фантастика:
фэнтези
попаданцы
5.25
рейтинг книги
Гром над Империей. Часть 2

Ритуал для призыва профессора

Лунёва Мария
Любовные романы:
любовно-фантастические романы
7.00
рейтинг книги
Ритуал для призыва профессора

Измена. Осколки чувств

Верди Алиса
2. Измены
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Измена. Осколки чувств