Как отсортировать массив по сходству по отношению к введенному слову. - PullRequest
15 голосов
/ 28 августа 2011

У меня есть массив PHP, например:

$arr = array("hello", "try", "hel", "hey hello");

Теперь я хочу переставить массив, который будет основан на самых близких словах между массивом и моим $ search var.

Как я могу это сделать?

Ответы [ 5 ]

16 голосов
/ 13 сентября 2016

Это может быть быстрое решение с использованием http://php.net/manual/en/function.similar-text.php:

. Это вычисляет сходство между двумя строками, как описано в Классике программирования: Реализация лучших алгоритмов мира Оливером (ISBN 0-131-00413-1).Обратите внимание, что эта реализация не использует стек, как в псевдокоде Оливера, но рекурсивные вызовы, которые могут или не могут ускорить весь процесс.Также обратите внимание, что сложность этого алгоритма составляет O (N ** 3), где N - длина самой длинной строки.

$userInput = 'Bradley123';

$list = array('Bob', 'Brad', 'Britney');

usort($list, function ($a, $b) use ($userInput) {
    similar_text($userInput, $a, $percentA);
    similar_text($userInput, $b, $percentB);

    return $percentA === $percentB ? 0 : ($percentA > $percentB ? -1 : 1);
});

var_dump($list); //output: array("Brad", "Britney", "Bob");

Или с использованием http://php.net/manual/en/function.levenshtein.php:

Расстояние Левенштейна определяется как минимальное количество символов, которое вы должны заменить, вставить или удалить, чтобы преобразовать str1 в str2.Сложность алгоритма составляет O (m * n), где n и m - это длина str1 и str2 (довольно хорошо по сравнению с похожим_текстом (), который равен O (max (n, m) ** 3), новсе еще дорого).

$userInput = 'Bradley123';

$list = array('Bob', 'Brad', 'Britney');

usort($list, function ($a, $b) use ($userInput) {
    $levA = levenshtein($userInput, $a);
    $levB = levenshtein($userInput, $b);

    return $levA === $levB ? 0 : ($levA > $levB ? 1 : -1);
});

var_dump($list); //output: array("Britney", "Brad", "Bob");
5 голосов
/ 28 августа 2011

Вы можете использовать Левенштейн функция

<?php
// input misspelled word
$input = 'helllo';

// array of words to check against
$words  = array('hello' 'try', 'hel', 'hey hello');

// no shortest distance found, yet
$shortest = -1;

// loop through words to find the closest
foreach ($words as $word) {

    // calculate the distance between the input word,
    // and the current word
    $lev = levenshtein($input, $word);

    // check for an exact match
    if ($lev == 0) {

        // closest word is this one (exact match)
        $closest = $word;
        $shortest = 0;

        // break out of the loop; we've found an exact match
        break;
    }

    // if this distance is less than the next found shortest
    // distance, OR if a next shortest word has not yet been found
    if ($lev <= $shortest || $shortest < 0) {
        // set the closest match, and shortest distance
        $closest  = $word;
        $shortest = $lev;
    }
}

echo "Input word: $input\n";
if ($shortest == 0) {
    echo "Exact match found: $closest\n";
} else {
    echo "Did you mean: $closest?\n";
}

?>
2 голосов
/ 28 августа 2011

если вы хотите отсортировать массив, вы можете сделать это:

$arr = array("hello", "try", "hel", "hey hello");
$search = "hey"; //your search var

for($i=0; $i<count($arr); $i++) {
   $temp_arr[$i] = levenshtein($search, $arr[$i]);
}
asort($temp_arr);
foreach($temp_arr as $k => $v) {
    $sorted_arr[] = $arr[$k];
}

$sorted_arr должен быть в порядке убывания, начиная с ближайшего слова к вашему поисковому запросу.

1 голос
/ 28 августа 2011

Другой способ - использовать функцию Similar_text , которая возвращает результат в процентах. Подробнее http://www.php.net/manual/en/function.similar-text.php.

0 голосов
/ 17 апреля 2018

пример для сортировки мультимассива схожим текстом https://3v4l.org/XUBDD#output

<?php
$json = '{
    "result": {
        "anime": [
            {
                "rowid": "2",
                "title": "Dusk Maiden of Amnesia",
                "pic": "\/\/i.imgur.com\/J4HRnHP.jpg",
                "slug": "Dusk-Maiden-of-Amnesia-dub",
                "year": "2012",
                "status": "done",
                "descript": "The story revolves around a first-year middle school student, Teiichi Niiya who had just enrolled at Seikyou Private Academy. When he gets lost in one of the schools old buildings, he meets a girl named Yuuko Kanoe who reveals herself as a ghost with no memories. Teiichi then decides to investigate her death by looking through the schools seven mysteries revolving around her. Throughout the story, Teiichi and Yuuko discover the truth about these ghost stories while helping those who are troubled.",
                "tags": "Mystery,,Romance,,School Club,,School Life,,Supernatural,,High School"
            },
            {
                "rowid": "12",
                "title": "Accel World",
                "pic": "https:\/\/i.imgur.com\/65gNsOX.png",
                "slug": "Accel-World-dub",
                "year": "2012",
                "status": "done",
                "descript": "Haruyuki+%22Haru%22+Arita+is+a+short%2C+overweight+boy+who+is+frequently+ridiculed+by+delinquents+at+the+Umesato+Junior+High+School.+Using+his+Neuro+Linker+to+escape+the+torment+of+real+life%2C+he+logs+onto+the+school%27s+Local+Network+cyberspace+where+he+always+plays+virtual+squash+alone%2C+and+his+innate+video+game+skills+bring+him+to+the+attention+of+Kuroyukihime+%28literally+meaning+%22Black+Snow+Princess%22%29%2C+the+school%27s+popular%2C+highly+intellectual+and+attractive+female+Student+Council+Vice-President.++After+helping+him+against+the+delinquents%2C+Kuroyukihime+introduces+Haruyuki+to+Brain+Burst%2C+a+secret+program+that+is+able+to+accelerate+the+human+cognitive+process+to+the+point+at+which+time+appears+to+stop.+Haruyuki+soon+learns+that+Brain+Burst+is+more+than+just+a+program%2C+but+an+Augmented+Reality+Massively+Multiplayer+Online+%28ARMMO%29+Fighting+Game+where+people+fight+each+other+in+fierce+duels+in+order+to+obtain+Burst+Points+which+can+be+spent+for+acceleration+abilities+in+the+real+world.",
                "tags": "Action,,Sci Fi,,Based On A Light Novel,,Futuristic,,Virtual Reality"
            },
            {
                "rowid": "7",
                "title": "Parasyte the maxim",
                "pic": "https:\/\/i.imgur.com\/AY7WkqY.jpg",
                "slug": "Parasyte-the-maxim-dub",
                "year": "2014",
                "status": "done",
                "descript": "17-year-old+Izumi+Shinichi+lives+with+his+mother+and+father+in+a+quiet+neighborhood+in+Tokyo.+One+night%2C+worm-like+aliens+called+Parasytes+invade+Earth%2C+taking+over+the+brains+of+human+hosts+by+entering+through+their+ears+or+noses.+One+Parasyte+attempts+to+crawl+into+Shinichi%27s+ear+while+he+sleeps%2C+but+fails+since+he+is+wearing+headphones%2C+and+enters+his+body+by+burrowing+into+his+arm+instead%2C+taking+over+his+right+hand+and+is+named+Migi.+Because+Shinichi+was+able+to+prevent+Migi+from+traveling+further+up+into+his+brain%2C+both+beings+retain+their+separate+intellect+and+personality.+As+the+duo+encounter+other+Parasytes%2C+they+capitalize+on+their+strange+situation+and+gradually+form+a+strong+bond%2C+working+together+to+survive.+This+gives+them+an+edge+in+battling+other+Parasytes%2C+who+frequently+attack+the+pair+upon+realization+that+Shinichi%27s+human+brain+is+still+intact.+Shinichi+feels+compelled+to+fight+other+Parasytes%2C+who+devour+humans+as+food%2C+while+enlisting+Migi%27s+help.",
                "tags": "Action,,Horror,,Sci Fi,,Aliens,,Body Sharing,,Bullying,,Explicit Violence,,Psychological"
            }
        ],
        "Current_page": "1",
        "Total_Pages": 75,
        "PerPage": 3,
        "Total": 224
    }
}';
$userInput = "maxim";
$jsonf = json_decode($json, true);
  usort($jsonf['result']['anime'], function ($a, $b) use ($userInput) {
    similar_text($userInput, $a['title'], $percentA);
    similar_text($userInput, $b['title'], $percentB);

    return $percentA === $percentB ? 0 : ($percentA > $percentB ? -1 : 1);
}); 
echo json_encode($jsonf);
?>
...