За последние 24 часа нас посетили 51424 программиста и 1759 роботов. Сейчас ищут 904 программиста ...

Соединить части строки всеми возможными комбинациями

Тема в разделе "PHP для новичков", создана пользователем MrDio, 19 июл 2017.

  1. MrDio

    MrDio Новичок

    С нами с:
    19 май 2017
    Сообщения:
    21
    Симпатии:
    0
    Есть строка разбирая на слова и помещенная в массив:
    PHP:
    1. $parts=Array('yamaha','dtx', '400');
    Есть варианты соединителей этих слов: тире, пробел, слитное написание
    PHP:
    1. $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 часа сижу пробую разные варианты, не получается. Наверняка должно быть какое-то красивое решение. Помогите пожалуйста.
     
  2. Ganzal

    Ganzal Суперстар
    Команда форума Модератор

    С нами с:
    15 мар 2007
    Сообщения:
    9.893
    Симпатии:
    965
    через вложенные циклы вполне решается. показывай как пробовал
     
  3. MrDio

    MrDio Новичок

    С нами с:
    19 май 2017
    Сообщения:
    21
    Симпатии:
    0
    Да честно-говоря конкретного рабочего кода так и не смог написать.
    Алгоритм думал такой:
    1. Берем первое и следующее значение из $parts и объединяем их через символы из $jumpers
    2. Сохраняем получившиеся варианты в какой-то массив:
    PHP:
    1. $tmp_array = Array('yamaha-dtx', 'yamaha dtx', 'yamahadtx')
    3. Далее берем уже эти элементы из $tmp_array и объединяем еще со следующим значением из parts и опять сохраняем уже 9 значений.
    И так далее. Но как это реализовать на практике, чтобы работало. Не понимаю.
     
  4. Ganzal

    Ganzal Суперстар
    Команда форума Модератор

    С нами с:
    15 мар 2007
    Сообщения:
    9.893
    Симпатии:
    965
    у тебя две позиции для подстановки следовательно тебе нужно дважды итерировать склеивающие символы. и уже внутри второго цикла делать конкатенацию.
    давай с другой стороны зайдем: какую задачу ты пытаешься этим велосипедом порешать?
     
  5. MrDio

    MrDio Новичок

    С нами с:
    19 май 2017
    Сообщения:
    21
    Симпатии:
    0
    Задача - поиск.
    Реальный пример: есть название товара
    yamaha dtx400k

    В базах у разных поставщиков он может быть записан как:
    yamaha dtx-400k
    yamaha dtx 400k
    yamaha dtx400 k

    С брендом (yamaha) все просто, он всгда однозначен.
    А вот с моделью проблема. Поэтому я бью модель на части: dtx, 400, k а потом ищу все возможные варианты написания.
     
  6. Ganzal

    Ganzal Суперстар
    Команда форума Модератор

    С нами с:
    15 мар 2007
    Сообщения:
    9.893
    Симпатии:
    965
    ищешь где?
     
  7. MrDio

    MrDio Новичок

    С нами с:
    19 май 2017
    Сообщения:
    21
    Симпатии:
    0
    В базе MySQL
     
  8. Ganzal

    Ganzal Суперстар
    Команда форума Модератор

    С нами с:
    15 мар 2007
    Сообщения:
    9.893
    Симпатии:
    965
    покури полнотекстовый индекс и не надо половых извращений
     
  9. MrDio

    MrDio Новичок

    С нами с:
    19 май 2017
    Сообщения:
    21
    Симпатии:
    0
    Подсказали stackoverflow. Копирну сюда, может быть кому-то тоже будет полезно:

    PHP:
    1. <?php
    2. function make($parts, $jumpers, $tail){
    3.     $part = array_shift($parts);
    4.     if($tail===''){
    5.         make($parts, $jumpers, $part);
    6.         return;
    7.     }
    8.     foreach($jumpers as $jumper){
    9.         if(empty($parts)){
    10.             echo $tail.$jumper.$part.PHP_EOL;
    11.         }else{
    12.             make($parts, $jumpers, $tail.$jumper.$part);
    13.         }
    14.     }
    15. }
    16.  
    17. $parts=Array('yamaha','dtx', '400');
    18. $jumpers=Array('-',' ', '');
    19.  
    20. make($parts, $jumpers, '');
     
  10. Ganzal

    Ganzal Суперстар
    Команда форума Модератор

    С нами с:
    15 мар 2007
    Сообщения:
    9.893
    Симпатии:
    965
    @MrDio это не решение твоей задачи, ты это понимаешь?
     
    Maputo нравится это.
  11. MrDio

    MrDio Новичок

    С нами с:
    19 май 2017
    Сообщения:
    21
    Симпатии:
    0
    В принципе задача решаема таким образом. Но нашли вроде еще лучшее решение.
    Нормализуем сначала данные в базе до "yamahadtx400" и потом ищем уже именно таком соответствию. Получается, вроде, лучше. Сейчас переделываю. Надеюсь сегодня доделаю.
     
  12. Ganzal

    Ganzal Суперстар
    Команда форума Модератор

    С нами с:
    15 мар 2007
    Сообщения:
    9.893
    Симпатии:
    965
    Ну да... Чем больше слов составляет искомое выражение тем бОльшим кол-вом лексем поиска нагружаем субд. И всего лишь в геометрической прогрессии. А так конечно решаема.

    Вот эта мысль уже лучше
     
  13. Maputo

    Maputo Активный пользователь

    С нами с:
    30 июл 2015
    Сообщения:
    1.136
    Симпатии:
    173
    Я ожидал, что с Вашей помощью он к этой мысли придет) Я так думаю, Вы упустили один момент - сначала надо было дать человеку, то что он хочет. Но это чисто мое мнение. А так - респект.
     
  14. Ganzal

    Ganzal Суперстар
    Команда форума Модератор

    С нами с:
    15 мар 2007
    Сообщения:
    9.893
    Симпатии:
    965
    @Maputo Не всегда можно сделать нормализацию данных, поэтому одна неплохая мысль уже была озвучена мной ранее - банальный полнотекстовый индекс и простейший матч-эгегейнст. Нормализация не спасет, если я не знаю как правильно пишется iamakha а полнотекст может и срелевантит пару-тройку строк.
     
    Maputo нравится это.
  15. MrDio

    MrDio Новичок

    С нами с:
    19 май 2017
    Сообщения:
    21
    Симпатии:
    0
    Всем спасибо!
    Вчера вечером дописал, вроде ищет неплохо. Дополнил еще небольшим словарем с вариантами написания типа:
    x air xr12 > xr12
    При получении из базы нескольких значений добавил коэффициент, который показывает разницу в длине искомой фразы и полученной, упорядочел по возрастанию и пока вообще все здорово. Продолжаю экспериментировать, наверное, что-то еще нужно будет добавить.