Есть строка разбирая на слова и помещенная в массив: PHP: $parts=Array('yamaha','dtx', '400'); Есть варианты соединителей этих слов: тире, пробел, слитное написание PHP: $jumpers=Array('-',' ', ''); Как красиво получить все возможные варианты объединения слов, через заданные соединители. Сейчас у меня сделано тупо вручную. В данном случае получится 9 вариантов: yamaha-dtx-400 yamaha-dtx 400 yamaha-dtx400 yamaha dtx-400 yamaha dtx 400 yamaha dtx400 yamahadtx-400 yamahadtx 400 yamahadtx400 В реальности соединителей может быть не 3, а 4 и тогда количество вариантов резко возрастает. Вручную совсем никак уже. Понимаю, что как-то через вложенные циклы, но уже 3 часа сижу пробую разные варианты, не получается. Наверняка должно быть какое-то красивое решение. Помогите пожалуйста.
Да честно-говоря конкретного рабочего кода так и не смог написать. Алгоритм думал такой: 1. Берем первое и следующее значение из $parts и объединяем их через символы из $jumpers 2. Сохраняем получившиеся варианты в какой-то массив: PHP: $tmp_array = Array('yamaha-dtx', 'yamaha dtx', 'yamahadtx') 3. Далее берем уже эти элементы из $tmp_array и объединяем еще со следующим значением из parts и опять сохраняем уже 9 значений. И так далее. Но как это реализовать на практике, чтобы работало. Не понимаю.
у тебя две позиции для подстановки следовательно тебе нужно дважды итерировать склеивающие символы. и уже внутри второго цикла делать конкатенацию. давай с другой стороны зайдем: какую задачу ты пытаешься этим велосипедом порешать?
Задача - поиск. Реальный пример: есть название товара yamaha dtx400k В базах у разных поставщиков он может быть записан как: yamaha dtx-400k yamaha dtx 400k yamaha dtx400 k С брендом (yamaha) все просто, он всгда однозначен. А вот с моделью проблема. Поэтому я бью модель на части: dtx, 400, k а потом ищу все возможные варианты написания.
Подсказали stackoverflow. Копирну сюда, может быть кому-то тоже будет полезно: PHP: <?php function make($parts, $jumpers, $tail){ $part = array_shift($parts); if($tail===''){ make($parts, $jumpers, $part); return; } foreach($jumpers as $jumper){ if(empty($parts)){ echo $tail.$jumper.$part.PHP_EOL; }else{ make($parts, $jumpers, $tail.$jumper.$part); } } } $parts=Array('yamaha','dtx', '400'); $jumpers=Array('-',' ', ''); make($parts, $jumpers, '');
В принципе задача решаема таким образом. Но нашли вроде еще лучшее решение. Нормализуем сначала данные в базе до "yamahadtx400" и потом ищем уже именно таком соответствию. Получается, вроде, лучше. Сейчас переделываю. Надеюсь сегодня доделаю.
Ну да... Чем больше слов составляет искомое выражение тем бОльшим кол-вом лексем поиска нагружаем субд. И всего лишь в геометрической прогрессии. А так конечно решаема. Вот эта мысль уже лучше
Я ожидал, что с Вашей помощью он к этой мысли придет) Я так думаю, Вы упустили один момент - сначала надо было дать человеку, то что он хочет. Но это чисто мое мнение. А так - респект.
@Maputo Не всегда можно сделать нормализацию данных, поэтому одна неплохая мысль уже была озвучена мной ранее - банальный полнотекстовый индекс и простейший матч-эгегейнст. Нормализация не спасет, если я не знаю как правильно пишется iamakha а полнотекст может и срелевантит пару-тройку строк.
Всем спасибо! Вчера вечером дописал, вроде ищет неплохо. Дополнил еще небольшим словарем с вариантами написания типа: x air xr12 > xr12 При получении из базы нескольких значений добавил коэффициент, который показывает разницу в длине искомой фразы и полученной, упорядочел по возрастанию и пока вообще все здорово. Продолжаю экспериментировать, наверное, что-то еще нужно будет добавить.