Я пытаюсь написать функцию, которая принимает следующие 2 параметра:
Итак, если бы я позвонил formatLines («Меня зовут Гэри», 2); ...
Возможные результаты:
Он вернет: array («Меня зовут», «это Гэри»);, потому что разница в количестве символов для каждой строки настолько мала, насколько это возможно.
Итак, часть, на которой я в конечном итоге застрял, - это создание массива возможных результатов, в котором слова находятся в правильном порядке, разделенные на x строк. Как только у меня будет набор возможных результатов, я смогу определить лучший результат.
Итак, как мне создать все возможные комбинации?
С Уважением
Джо
«потому что разница в количестве символов для каждой строки настолько мала, насколько это возможно» - это то, чего вы хотите достичь?
я думаю, вы найдете то, что ищете, в этом посте: stackoverflow.com/questions/5506888/…
@ NoOorZ24 да, я хочу, чтобы функция возвращала комбинацию, в которой средняя разница в количестве символов для каждой строки минимальна.
Спасибо @wayneOS, но это не поможет, так как возможные перестановки должны быть в правильном порядке слов
Разница в длине строки или разнице в количестве слов?
Так что для чего-то вроде «Миссисипи такой красивый», вернет ли он ["Mississippi is", "so nice"] (одинаковое количество слов) или ["Mississippi", "is so nice"] (наименьшее различие в длине строк)?
@Anthony, он должен вернуть ["Миссисипи", "это так красиво"], поскольку это наименьшая разница в длине строки. Да.






Похоже, что создание всех возможных способов разделения текста с последующим определением лучшего было бы излишне неэффективным. Вы можете подсчитать символы и разделить их на количество строк, чтобы найти приблизительно правильное количество символов в строке.
function lineSplitChars($text, $lines) {
if (str_word_count($text) < $lines) {
throw new InvalidArgumentException('lines must be fewer than word count', 1);
}
$width = strlen($text) / $lines; // initial width calculation
while ($width > 0) {
$result = explode("\n", wordwrap($text, $width)); // generate result
// check for correct number of lines. return if correct, adjust width if not
$n = count($result);
if ($n == $lines) return $result;
if ($n > $lines) {
$width++;
} else {
$width--;
};
}
}
Спасибо @ Don't Panic, но эта функция, если дана строка из 3 слов на 2 строки, возвращает массив с 3 словами ... функция должна возвращать только массив со счетом, таким же, как количество строк
Ах, да, я понимаю, как это могло случиться. Я думаю, что это все еще может работать таким образом. Я внесу поправку.
Спасибо за вашу помощь
@Joeseppi Я изменил функцию, чтобы повторить попытку с увеличенной шириной строки, пока не будет получено правильное количество строк.
Следует иметь в виду, что некоторые сценарии не могут быть выполнены, в частности: formatLines("Hello World", 3). Должно ли это вызвать исключение? Или вернуть массив с 2 записями? Или вернуть массив типа ["Hello", "World", ""]?
Это работает лучше, но после прохождения некоторых тестовых примеров, таких как: lineSplitChars ("hukjfbvsjvbnvlsknv j kjds", 3);, где первое слово довольно длинное, он возвращает только 2 строки!
@Anthony, я фактически рассмотрел это за пределами функции, чтобы определить, меньше ли количество слов, чем количество строк, а затем строк = количество слов, а затем передается в функцию.
@ Энтони Да, это правда. Я должен упомянуть об этом в ответе. Я не думаю, что это действительно законченный продукт. Просто идея другого способа сделать это, которую можно расширить. Тем не менее, я все же хотел бы попытаться заставить его работать. Думаю, это интересная проблема.
@Joeseppi О да, я думаю, он должен изменить ширину линии, если count <lines.
Это хорошо, но функция этого не узнает. Как бы вы хотели, чтобы он отреагировал, если бы столкнулся с таким сценарием?
@Anthony Я написал сценарий, который автоматически генерирует рекламные объявления нескольких размеров для 200+ продуктов, поэтому, учитывая размеры рекламы, у меня есть выделенный размер для названия продукта, поэтому сценарий всегда будет знать, сколько строк в нем доступно, Затем скрипт выполнит цикл по строкам, возвращаемым проблемной функцией, и применит текст к изображениям. Таким образом, в случае, если слов меньше, чем доступных строк, доступные строки, переданные в функцию, будут равны количеству слов.
@Joeseppi, хорошо, новая версия, ха-ха. теперь уменьшает ширину, если count <строк. Также добавлено исключение для недопустимого ввода. Не знаю, как вы хотите справиться с этим, но, по крайней мере, условие есть.
@ Не паникуй, ты спас мне день! Пройдены все тесты, которые я настроил. Огромное спасибо!
@Joeseppi отлично! Думаю, я немного недооценил сложность.
@ Don't Panic, ты должен увидеть, сколько у меня каракулей на бумаге благодаря моему оригинальному подходу! Я ценю вашу помощь.
Это действительно впечатляет. Одна из возможных ошибок заключается в том, как str_word_count определяет границы слов. Из примера в их документации fri3nd будет считаться 2 словами.
@ Энтони, спасибо! Я никогда не замечал этого в str_word_count. Возможно, было бы лучше просто подсчитать пробелы или использовать для этой части регулярное выражение. (Говоря о регулярных выражениях, вероятно, есть какой-то способ сделать все это с помощью одного preg_split или чего-то еще, что заставит этот подход выглядеть глупо. К сожалению, я не очень разбираюсь в регулярных выражениях, поэтому я даже не знаю, с чего начать.)
Здесь был принят ответ, но это кажется мне довольно громоздким методом решения проблемы, когда PHP уже предоставляет функцию wordwrap (), которая выполняет большую часть тяжелой работы:
function format_lines($str, $lines)
{
$guess_length=(integer)(strlen($str)/($lines+1));
do {
$out=explode("\n", wordwrap($str, $guess_length));
$guess_length++;
} while ($guess_length<strlen($str) && count($out)>$lines);
return $out;
}
В его нынешнем виде это скорее метод грубой силы, и для очень больших входных данных лучшее решение будет использовать оптимальный поиск (добавление / удаление большего начального интервала, а затем уменьшение его в итерациях)
Мне нравится идея уменьшить длину предположения в начале с $lines+1, поэтому вам нужно только увеличить длину предположения! Это все упрощает. Это похоже на то, как будто вы говорите, что мой ответ не использует wordrap. Я неправильно понял?
перестановки - это слово, которое вы ищете.