Прежде всего, если это утверждение верно, ситуация безнадежна:
но эти утверждения не упорядочены (и я не могу их упорядочить).
Неупорядоченный список операторов исправления может привести к конфликту.Невозможно решить, какой правильный ответ будет сделан автоматически.Например, рассмотрим следующую ситуацию:
0 1 2
index: 012345678901234567890
text: "apple banana coconuts"
- delete 5 characters from index 10
- add "xyz" at index 10
- delete 10 characters from index 5
В результате вы получите различные результаты в зависимости от того, в каком порядке вы выполняете эти операторы .
Например, если вы примените (1), затем (2), затем (3), вы получите «apple banaconuts» -> «apple banaxyzconuts» -> «apple uts».
Но если вы примените (3), затем (2), а затем (1), вы получите «apple onuts» -> «apple onutsxyz» -> [error - thereнедостаточно символов для удаления!] .
Либо вам требуется повторяющееся согласованное упорядочение утверждений, либо вы не можете продолжить работу.Хуже того, оказывается, что обнаружение того, какие упорядочения являются действительными (например, устранение всех упорядочений, где встречается невозможное утверждение, например «удалить 10 символов из индекса 20», когда нет индекса 20), является неразрешимая проблема информатики .
Если окажется, что исправления могут быть применены в определенном порядке (или, по крайней мере, в повторяющемся, согласованном, детерминированном порядке), ситуация улучшается, но все еще неприятна.Поскольку индексы в любом «патче» могут быть признаны недействительными по сравнению с любым предыдущим, не представляется возможным напрямую применить каждое утверждение.Вместо этого вам придется реализовать небольшой псевдо-diff
.Вот как я это сделаю:
- Просматривать список операторов-патчей.Составьте список операций .Операция - это объект с командой и некоторыми необязательными аргументами и index для применения этой команды.Например, ваши операции могут выглядеть следующим образом:
DeleteOperation(index 3, length 4)
AddOperation(index 3, text "surname")
DeleteOperation(index 20, length 5)
По мере выполнения операций сохраняйте ссылку на исходную строку и сохраняйте «грязный»указатель".Это последний непрерывный индекс в строке, в котором не было выполнено никаких операций.Любая выполняемая вами операция, индекс которой превышает «грязный» указатель, должна быть предварительно обработана.
Если вы встретите чистую операцию, индекс которой меньше или равен «грязному» указателю, выможет применить его без дальнейшей работы.Грязный указатель теперь перемещается к индексу этой операции.
Если вы столкнулись с грязной операцией, индекс которой больше, чем грязный указатель, вам придется выполнить некоторую работу, прежде чем вы сможетеприменить это.Определите реальный индекс того, где операция должна применяться, просмотрев предыдущие операции, затем сделайте соответствующее смещение и примените его.
Выполняйте каждую операцию по очереди, пока не останется больше операцийвыполнить.
Результатом будет ваша преобразованная строка.