Существует линейный алгоритм времени для равномерного разбиения текста на строки максимальной ширины. Он использует SMAWK (или Knuth & Plass) и «равномерно» означает: http://en.wikipedia.org/wiki/Word_wrap#Minimum_raggedness
Существует ли алгоритм или вогнутая функция стоимости для алгоритма, описанного выше, которая бы учитывала количество строк, на которые я хотел бы разбить текст, вместо максимальной ширины строки? Также в линейное время?
Другими словами, я ищу алгоритм разрыва строки (или формирования абзаца, или переноса слов), в котором вводом является желаемое количество строк, а не желаемая ширина строки.
Просто для описания практически непригодного подхода: между каждой парой слов есть N слов и N-1 пробелов, M - желаемое количество строк (M <= N). После каждого пробела может быть не более одного (возможно, нулевого) переноса строки. Теперь алгоритм будет пытаться поместить разрывы в каждую возможную комбинацию, вычисляя «неровность» и возвращая лучшую. Как сделать это намного быстрее?
Кроме того, у такой проблемы есть имя? К какой «семье» проблем это относится? (Например, «упаковка в мусорное ведро»). Если мне не понадобится совершенно оптимальное решение, просто очень хорошее, можно ли решить его намного быстрее? (некоторая форма эвристики могла бы быть полезной, если бы для данного входа всегда было одно и то же, возможно, неоптимальное, решение).
Обновить
Чандра Чекури предложил ниже «проблему в главе Клейнберга и Тардоса о динамическом программировании». Это было хорошее чтение, но оно имеет дело с разрывом строки на основе ширины, а не количества строк. Это может быть приспособлено к этой проблеме, которую я сейчас пытаюсь выяснить. Вот хорошая ссылка на решение, они даже утверждают, что решают его за линейное время: http://web.media.mit.edu/~dlanman/courses/cs157/HW5.pdf
Кроме того, в «Руководстве по проектированию алгоритмов» Skiena есть глава «8.5. Проблема разбиения», которая, кажется, в точности соответствует теме, я все еще читаю ее. (К сожалению, из того, что я понял, это имеет сложность квадратичного времени)
источник
Ответы:
источник
Я не знаю, помогает ли это, но ближе к концу этого комментария кто-то реализует то, что вы хотите в PHP; может быть, вы можете выяснить алгоритм.
источник
wordwrap()
, который, в свою очередь, использует жадный (т.е. не «равномерный») алгоритм для переноса. Даже тогда остается вопрос, как «угадать»$width
аргументwordwrap()
. Но все равно спасибо за ответ!