Как я могу разумно эффективно найти кратчайший вывод, заданный путем многократного применения замен во входную последовательность? Я верю (пожалуйста, поправьте меня, если я ошибаюсь), что это экспоненциальное время в худшем случае, но я не уверен из-за второго ограничения ниже. Наивный метод, безусловно, есть.
Я пробовал кодировать наивный метод (для всех возможных замещений для всех допустимых позиций рекурсия на копии ввода после применения замены в позиции. Возвращает самую короткую из всех допустимых рекурсий и ввода с кешем на функция улавливать эквивалентные последовательности замещения), но она (неработоспособная) медленная, и я уверен, что это алгоритмическая проблема, а не реализация.
Несколько вещей, которые могут (или не могут) иметь значение:
- Токен - это перечисляемый тип.
- Длина вывода каждой записи на карте строго меньше входной записи.
- Мне не нужны, какие замены были сделаны, и где, только результирующая последовательность.
Итак, в качестве примера, где каждый символ является токеном (для простоты), если у меня есть замена карты как aaba
→ a
, aaa
→ ab
и aba
→ bb
, и я применяю minimumString ('aaaaa'), я хочу получить 'a'.
Фактическая подпись метода - это что-то в следующих строках:
List<Token> getMinimalAfterReplacements(List<Token> inputList, Map<List<Token>, List<Token>> replacements) {
?
}
Есть ли лучший способ, чем грубая сила? Если нет, существует ли, например, библиотека SAT или подобное, которое можно было бы использовать? Есть ли какая-либо предварительная обработка карты, которую можно было бы сделать, чтобы сделать ее более быстрой, когда она вызывается несколько раз с разными списками токенов, но с той же картой замены?