Переставить слова в массиве в соответствии с позицией, вычисляя расстояние Левенштейна Переполнение стека

Перестановка слов в массиве на основе положения первого массива. В моем коде есть два массива, мой первый массив — это базовый массив, из которого я собираюсь сравнить его со вторым массивом и сделать позицию такой же, как в первом массиве.

Рассмотрим 2 ввода, считая 1 входной базой, я применяю левенштейн (метафон (каждая база данных слов), метафон (каждое слово банка)), а затем на основе того, что слова банка данных размещаются в новом массиве.

databaseName = LAL BAHADUR SHASTRI
bankdata = SHASTRI LAL исходный код будет только переупорядочивать банковские данные и сохраняться в новом массиве текущего вывода bankdata : LAL SHASTRI

Перестановка происходит правильно, просто нужно упорядочить слова в массиве

        $db = 'LAL BAHADUR SHASTRI YADAV';
$bank = 'SHASTRI LAL';
$a = reArrangeArray($db,$bank);

function reArrangeArray($db,$bank)
{
$dataBaseName = $db;
$bankdataRows = [$db,$bank,];
$dbWords = preg_split("#[\s]+#", $dataBaseName);
foreach ($bankdataRows as $bankdata)
{
$bankWords = preg_split("#[\s]+#", trim($bankdata));
$result    = [];
if(!empty($bankWords))
foreach ($dbWords as $dbWord)
{
$idx   = null;
$least = PHP_INT_MAX;
foreach ($bankWords as $k => $bankWord)
if (($lv = levenshtein(metaphone($bankWord),metaphone($dbWord))) < $least)
{
$least = $lv;
$idx   = $k;
}
@$result[] = $bankWords[$idx];
unset($bankWords[$idx]);
}
$result = array_merge($result, $bankWords);
var_dump($result);
}
}

Случай 1: ТЕКУЩИЙ ВЫХОД

        array (size=4)
0 => string 'LAL' (length=3)
1 => string 'BAHADUR' (length=7)
2 => string 'SHASTRI' (length=7)
3 => string 'YADAV' (length=5)

array (size=4)
0 => string 'LAL' (length=3)
1 => string 'SHASTRI' (length=7)
2 => null
3 => null

Ожидаемый результат

Мне нужно положение массива так же, как базы данных

        $dbName = 'LAL BAHADUR SHASTRI YADAV';
$bankName = 'SHASTRI LAL';

array of db (size=4)
0 => string 'LAL' (length=3)
1 => string 'BAHADUR' (length=7)
2 => string 'SHASTRI' (length=7)
3 => string 'YADAV' (length=5)

array of bankname (size=4)
0 => string 'LAL' (length=3)
1 => #
2 => string 'SHASTRI' (length=7)
3 => ###

если слово не найдено в первом массиве, оно должно быть помещено с #, поскольку позиция равна 3, у которой нет соответствующего элемента, у него есть 3 #

        array (size=4)
0 => string 'LAL' (length=3)
1 => string 'BAHADUR' (length=7)
2 => string 'SHASTRI' (length=7)
3 => string 'YADAV' (length=5)

array (size=4)
0 => string 'LAL' (length=3)
1 => string 'SHASTRI' (length=7)
2 => null
3 => null

Ожидаемый результат

Мне нужно положение массива так же, как базы данных

        $dbName = 'LAL BAHADUR SHASTRI YADAV';
$bankName = 'SHARI LAL';

array of db (size=4)
0 => string 'LAL' (length=3)
1 => string 'BAHADUR' (length=7)
2 => string 'SHASTRI' (length=7)
3 => string 'YADAV' (length=5)

array of bankname (size=4)
0 => string 'LAL' (length=3)
1 => #
2 => string 'SHARI' (length=7)
3 => ###

Этот случай будет рассчитан на основе levenshtein(metaphone($bankWord),metaphone($dbWord))

Дело 2

Вход:

$dbName = NikithaRani MohanRao $bankdata = Nikitha Rani Mohan Rao

Output : $newbankdata = NikithaRani MohanRao

Должен объединять слова, если найден в $ dbName

Заметка

Положение слова рассчитывается просто нужно сдвинуть слово в массиве путем сравнения первого массива

Ожидаемый результат

Диаграмма проблемы

-2

Решение

Я не уверен, что понимаю весь вопрос, но давайте попробуем решить только проблему перестановки массива:

$a1 = explode(" ", "LAL BAHADUR SHASTRI YADAV");
// sort $a1 to whatever order you need
$a2 = explode(" ", "SHASTRI LAL");

foreach($a1 as $key => $e) { // for each element set him or fill with "#"$res[$key] = in_array($e, $a2) ? $e : str_repeat("#", $key);
}

ул-повтор является дубликатом символа для x раз. Этот код работал в O(n*m) — это можно изменить O(n) если нужно (когда n номер элемента в первом массиве).

Я надеюсь, что это помогает, и если не стесняйтесь комментировать

Отредактировано:

Сначала определим функцию для нахождения минимального расстояния Левенштейна:

function foundLevenshteinMinIndex($word, $arr) {
$word = metaphone($word);
foreach ($arr as $k =>$e)
$a[] = levenshtein($word,metaphone($e));
return array_search(min($a), $a);
}

Сейчас использовал то же самое $a1, $a2 как сделать:

foreach($a2 as $w) {
$i = foundLevenshteinMinIndex($w, $a1);
if (!isset($res[$i]) || (levenshtein(metaphone($a1[$i]), metaphone($res[$i])) > levenshtein(metaphone($a1[$i]), metaphone($w))))
$res[$i] = $w;
}

for($i = 0; $i < count($a1); $i++)
if (!isset($res[$i])) // if not set in the index fill with "#'
$res[$i] = str_repeat("#", $i);
// rearrange by int indexs
ksort($res);

Отредактировано 2

Посмотрите на эту реализацию:

$a1 = explode(" ", 'LAL BAHADUR SHASTRI YADAV');
$a2 = explode(" ",'SHASTRI LAL NABA');

function getDist($a1, $a2) {
foreach($a2 as $k1 => $w1)
foreach($a1 as $k2 => $w2)
$arr[$k1][$k2] = levenshtein(metaphone($w1), metaphone($w2));
return $arr;
}

function getMin($arr) {
$min = PHP_INT_MAX;
$minX = $minY = null;
foreach($arr as $x => $row)
foreach($row as $y => $cell)
if ($cell < $min) {
$min = $cell;
$minX = $x;
$minY = $y;
}
return array($minX, $minY);
}

function removeIndex($arr, $x, $y) {
unset($arr[$x]);
foreach($arr as &$row)
unset($row[$y]);
return $arr;
}

$arr = getDist($a1, $a2);
while (count($arr) && count(reset($arr))) {
list($x, $y) = getMin($arr);
if (!isset($res[$y]))
$res[$y] = $a2[$x];
$arr = removeIndex($arr, $x, $y);
}

for($i = 0; $i < count($a1); $i++)
if (!isset($res[$i])) // if not set in the index fill with "#'
$res[$i] = str_repeat("#", $i);
ksort($res);

Обратите внимание, что этот код имеет временную сложность O(n*(m^2)) когда n это первый массив и m это второй

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]