【问题标题】:Can't use levenshtein() on a single array to compare and find elements with shortest distance不能在单个数组上使用 levenshtein() 来比较和查找距离最短的元素
【发布时间】:2014-09-01 16:20:37
【问题描述】:

无法使用 levenshtein() 来解决这个问题。

假设我有一个如下所示的数组:

Array
(
    [0] => Array
        (
            [Gammal URL] => /bil-och-garage
            [Ny URL] => /catalog/verktyg-och-maskiner
        )

    [1] => Array
        (
            [Gammal URL] => /bil-och-garage/12-v-utrustning
            [Ny URL] => /catalog/verktyg-och-maskiner/handverktyg
        )

    [2] => Array
        (
            [Gammal URL] => /bil-och-garage/12-v-utrustning/antenn
            [Ny URL] => /catalog/verktyg-och-maskiner/handverktyg/slag-brytverktyg
        )
)

我想要做的是打印数组,但要添加。我想要做的是遍历数组并对每个“Gammal URL”执行 levenshtein() 并找到与当前“Gammal URL”距离最短的“Ny URL”。

如果没有完全匹配 (0),则打印最短的那个。我一直在尝试使用嵌套的 foreach 的不同用途,但无法理解如何一次检查 1 个 url 和数组的其余部分。

简而言之,我想打印上面的整个数组,但第三列的 URL 距离最短。如果以上不是最佳解决方案,也欢迎任何使用两个数组的建议。

编辑

有了这个我仍然得到错误的 URL 作为“匹配的 URL” - 有什么想法吗?

foreach ($import as $key => $arr) {
      $shortest = '';
      foreach ($import as $key2 => $arr2) {
        if ($shortest != '') {
          // If the distance between the current Ny URL is shorted than the previously shortest one    :
          // -> it's the new shortest one, otherwise, I keep the previous one
          $shortest = (levenshtein($arr['Gammal URL'], $arr2['Ny URL']) < levenshtein($arr['Gammal   URL'], $shortest)) ? $arr2['Ny URL'] : $shortest;
        } else { // First attempt is set as the shortest aby default
          $shortest = $arr2['Ny URL'];
        }
      }
      // I found the shortest one for that Gammal URL
      $import[$key]['shortest'] = $shortest;

            echo'<tr>';
            echo'<td>'. $arr['Gammal URL']."</td>";
            echo'<td>'. $arr['Ny URL'].'</td>';
            echo'<td>'. $shortest .'</td>';

    }

完整代码

    <?php

//debug

ini_set('display_errors', 'On');
error_reporting(E_ALL);
ini_set('auto_detect_line_endings', TRUE);
ini_set('max_execution_time', 300);
?>


<?php

//import

function csv_import($filename='', $delimiter=';')
{
  if(!file_exists($filename) || !is_readable($filename))
    return FALSE;

  $header = NULL;
  $data = array();
  if (($handle = fopen($filename, 'r')) !== FALSE)
  {
    while (($row = fgetcsv($handle, 1000, $delimiter)) !== FALSE)
    {
      if(!$header)
        $header = $row;
      else
        $data[] = array_combine($header, $row);
    }
    fclose($handle);
  }
  return $data;
}

$import = csv_import('urler.csv');

//output

//print_r($import);

echo '<table>';
echo '<thead>';
echo '<tr>';
echo "<th>Gammal URL</th>";
echo "<th>Ny URL</th>";
echo "<th>Match URL</th>";
echo "</tr>";
echo "</thead>";
echo "</tbody>";

foreach ($import as $key => $arr) {
  $shortest = '';

  foreach ($import as $key2 => $arr2) {
    if ($shortest != '') {
      // If the distance between the current Ny URL is shorted than the previously shortest one :
      // -> it's the new shortest one, otherwise, I keep the previous one
      $shortest = (levenshtein($arr['Gammal URL'], $arr2['Ny URL']) < levenshtein($arr['Gammal URL'], $shortest)) ? $arr2['Ny URL'] : $shortest;
    } else { // First attempt is set as the shortest aby default
      $shortest = $arr2['Ny URL'];
    }
  }
  // I found the shortest one for that Gammal URL
  $import[$key]['shortest'] = $shortest;


        echo'<tr>';
        echo'<td>'. $arr['Gammal URL']."</td>";
        echo'<td>'. $arr['Ny URL'].'</td>';
        echo'<td>'. $shortest .'</td>';

  }

echo "</tbody>";
echo "</table>";

?>

【问题讨论】:

    标签: php arrays levenshtein-distance


    【解决方案1】:

    这应该可以完成工作:

    foreach ($array as $key => $arr) {
      $shortest = '';
      foreach ($array as $key2 => $arr2) {
        if ($shortest != '') {
          // If the distance between the current Ny URL is shorted than the previously shortest one :
          // -> it's the new shortest one, otherwise, I keep the previous one
          $shortest = (levenshtein($arr['Gammal URL'], $arr2['Ny URL']) < levenshtein($arr['Gammal URL'], $shortest)) ? $arr2['Ny URL'] : $shortest;
        } else { // First attempt is set as the shortest by default
          $shortest = $arr2['Ny URL'];
        }
      }
      // I found the shortest one for that Gammal URL
      $array[$key]['shortest'] = $shortest;
    }
    

    我猜你不是太远,因为你必须嵌套 foreach,但如果你需要更多解释,请在评论中询问

    【讨论】:

    • @Mikael 也许levenshtein 不是您正在寻找的功能吗?你能给出你当前的输出和想要的输出吗?
    • 我可以补充一点,当样本很小时,它可以工作,但是如果有几行,它就会中断,而且它似乎没有选择最短距离。
    • @Mikael 真的很奇怪。这段代码没有绑定任何增量值,或者只是在不同参数上的相同函数之间的比较
    • 嗯,用例是这样的:我需要将 2700 个旧网址与 2000 个新闻网址进行匹配。问题是它们之间没有明显的模式,除了一些部分和一些词在新旧网址中都使用。这意味着如果旧网址是 dog/dogfood/puppyfood,我需要将其与 pets/animalfood/puppyfood 或更好的匹配。据我所知,levenshetin() 是最合适的。输入是一个包含 2 列新旧 url 的 csv。输出应该是具有相同设置的表格,包括“最佳匹配”列,其中最佳匹配新网址与旧网址匹配。
    猜你喜欢
    • 1970-01-01
    • 2016-03-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-27
    • 2021-02-17
    • 1970-01-01
    • 2018-03-01
    相关资源
    最近更新 更多