erniesto77
@erniesto77
oop, mvc, rb, py, php, js

Как найти пересечения слов в строках и объединить в группы похожие строки (php)?

Допустим, дан массив таких строк:
'Концерт группы Ленинград'
'Группа ZebraHead'
'ZebraHead'
'Группа СПЛИН'
'Ленинград'
'Концерт группы ZebraHead'
'ZebraHead. Презентация альбома'
'СПЛИН в Олимпийском'
'Крематорий'
'Группировка Ленинград'


На выходе надо получить сгруппированные массивы по пересечениям слов в строках:
[0] => [ // пересечение Ленинград
    'Концерт группы Ленинград',
    'Ленинград',
    'Группировка Ленинград'
],
[1] => [ // пересечение ZebraHead
    'Группа ZebraHead',
    'ZebraHead',
    'Концерт группы ZebraHead',
    'ZebraHead. Презентация альбома',
],
[2] => [ // пересечение СПЛИН
    'Группа СПЛИН',
    'СПЛИН в Олимпийском',
]


Заранее всем спасибо!
  • Вопрос задан
  • 1505 просмотров
Решения вопроса 4
littleguga
@littleguga
Не стыдно не знать, а стыдно не интересоваться.
Примерно так: https://ideone.com/kylhD6

Конечно, надо немного доработать, чтобы определяло именно слова, а не совпадения по буквам. То есть сейчас он в Ленинград и "Ленинградский" запихнет.

upd:
https://ideone.com/aBSGzA
Допилил так, чтобы искал именно слова, а не просто вхождения строки.
Если нужно искать именно слова, то можно допилить так:
strpos(" ".$phrase." ", " ".$word." ") !== false

Исходный код:
spoiler
<?php
$arr = [
'Концерт группы Ленинград',
'Группа ZebraHead',
'ZebraHead',
'Группа СПЛИН',
'Ленинград',
'Концерт группы ZebraHead',
'ZebraHead. Презентация альбома',
'СПЛИН в Олимпийском',
'Крематорий',
'Группировка Ленинград'
];
$newarr = [];
 
$words = [];
$result = [];
 
foreach($arr as $key => $val){
    //приводим к нижнему регистру
    $val = strtolower($val);
 
    //убираем знаки препинания и прочие символы
    $val = str_replace(".", "", $val);
    $val = str_replace(",", "", $val);
    $val = str_replace("/", "", $val);
    $val = str_replace(";", "", $val);
    $val = trim($val);
 
    //запоминаем "очищенные" слова
    $newarr[$key] = $val;
 
    //разделяем слова в массив
    $cw = explode(" ", $val);
 
    //запоминаем весь список слов
    foreach($cw as $word){
    	array_push($words, $word);
    }
}
 
 
foreach($words as $word){
	$ca = [];
 
	foreach($newarr as $key => $phrase){
		//проверяем, что фраза содержит это слово
		if(strpos($phrase, $word) !== false){
			//если так, то запоминаем
			array_push($ca, $arr[$key]);
		}
	}
 
	$result[$word] = $ca;
}
 
print_r($result);

Ответ написан
Bowen
@Bowen
Геймер в отставке
В вашем массиве, в строках по несколько слов. Вы же, хотите создать отдельные массивы из строк этого массива, содержащие определенные слова(которые известны только вам).

Какие я вижу пути решения задачи:
  1. Передавать те самые определенные слова в функцию, которая будет разбирать этот массив. Где с помощью регулярного выражения, будут проверенны слова в строках....
  2. Выделять нужные вам слова каким то образом, например, переписать в верхнем регистре. Тогда, придется лишь переписать алгоритм в вашей функции, чтобы он искал только слова в вернем регистре.
Ответ написан
lxsmkv
@lxsmkv
Test automation developer
Токенайзер вроде бы вполне подойдет.
www.w3schools.com/php/func_string_strtok.asp
И алгоритм на первый взгляд вполне простой: для каждого токена в энной строке перебери все остальные строки и сохрани под ключом те, в которых встречается этот токен. Ну и конечно если токен уже занесен в ответную таблицу, то обходить все строки не нужно, потому что при первом занесении список для этого токена уже был сформирован (по первой инструкции).
Как-то так вобщем :)
Ответ написан
@danSamara
Без ошибок и без словаря, в котором будут выставлены веса для отдельных слов - никак.
Поясню. У вас стоит задача разбить строки с упором на музыкальные группы (отталкиваюсь от вашего примера), значит для всех названий групп должен стоять приоритет группировки, иначе объединение будет происходить случайным образом - по первым попавшимся словам.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы
DANYCOM Краснодар
от 50 000 до 100 000 ₽
ЧИТАЙ-ГОРОД Москва
от 140 000 до 210 000 ₽
ЭР-Телеком Пермь
от 80 000 ₽
30 мар. 2020, в 21:09
1000 руб./в час
30 мар. 2020, в 20:56
280000 руб./за проект
30 мар. 2020, в 20:22
25000 руб./за проект