Переставить слова, используя расстояние Левенштейна

Просто, чтобы закрыть вопрос для любой будущей возможной проверки. Решением, которое я использовал, было использование списка в списках. Таким образом, индексом элемента был порядок, а задачи и статус завершения были 0 и 1 элементами списка в списках.

2
задан Quasimodo's clone 20 January 2019 в 13:31
поделиться

2 ответа

Я разбил код в случаях 1 и 2.
Но очевидно, что если var_export имеет значение false, вы делаете код case 2 с теми же переменными.

//Case 1:
$DatabaseName = "Jardine Lloyd Thompson";
$BankName = "Thompson Jardine Lloyd";

//Split and sort them
$data = explode(" ", $DatabaseName);
$bank = explode(" ", $BankName);
sort($data);
sort($bank);
Var_export(($data == $bank)); //true

//Case 2
$DatabaseName = "Jardine Lloyd Thompson";
$BankName = "Thoapson Jordine Llayd";

//Split and sort
$data = explode(" ", $DatabaseName);
$bank = explode(" ", $BankName);
sort($data);
sort($bank);

// Loop and accumulate the levenshtein return
$lev = 0;
foreach($data as $key => $name){
    $lev += levenshtein($name, $bank[$key]);
}

echo PHP_EOL . $lev; // 3 letters "off"

https://3v4l.org/eP5PE

Пример случаев 1 и 2 в одном коде.

$DatabaseName = "Jardine Lloyd Thompson";
$BankName = "Thoapson Jordine Llayd";

$data = explode(" ", $DatabaseName);
$bank = explode(" ", $BankName);
sort($data);
sort($bank);
if($data == $bank){
    echo "true";
    exit;
    // No need to do levenshtein
}

$lev = 0;
foreach($data as $key => $name){
    $lev += levenshtein($name, $bank[$key]);
}

echo PHP_EOL . $lev;

https://3v4l.org/RJSiB

0
ответ дан Andreas 20 January 2019 в 13:31
поделиться

Это простая версия, которая впоследствии находит слово за словом наилучшее совпадение.

declare (strict_types=1);

$dataBaseName = 'Jardine Lloyd Thompson';

$bankdataRows =
[
  'Thompson Jardine Lloyd',
  'Blaaa  Llayd Thoapson   f***ing user input   Jordine   aso. ',
];

// assume the "database" is already stored trimmed since it is server-side controlled
$dbWords = preg_split("#[\s]+#", $dataBaseName);

foreach ($bankdataRows as $bankdata)
{
  // here we trim the data received from client-side.
  $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($bankWord, $dbWord)) < $least)
        {
          $least = $lv;
          $idx   = $k;
        }

      $result[] = $bankWords[$idx];
      unset($bankWords[$idx]);
    }

  $result = array_merge($result, $bankWords);
  var_dump($result);
}

результат

array(3) {
  [0] =>
  string(7) "Jardine"
  [1] =>
  string(5) "Lloyd"
  [2] =>
  string(8) "Thompson"
}

array(8) {
  [0] =>
  string(7) "Jordine"
  [1] =>
  string(5) "Llayd"
  [2] =>
  string(8) "Thoapson"
  [3] =>
  string(5) "Blaaa"
  [4] =>
  string(7) "f***ing"
  [5] =>
  string(4) "user"
  [6] =>
  string(5) "input"
  [7] =>
  string(4) "aso."
}

См. Живую скрипку

Возможно, вы захотите расширить этот подход, сначала вычислив расстояние Левенштейна каждую возможную комбинацию, а затем выберите лучший весь матч.

0
ответ дан Quasimodo's clone 20 January 2019 в 13:31
поделиться
Другие вопросы по тегам:

Похожие вопросы: