Левенштейн в PHP - PullRequest
       7

Левенштейн в PHP

0 голосов
/ 04 мая 2011

Я написал эти функции в модели (я использую CodeIgniter).

    function getLocalIngrdname()
{
    $this->load->database();
    $query = $this->db->get('onl_local_ingrd');
    foreach($query->result() as $row)
        $allingrd[]=$row->ingrd_localname;
    return $allingrd;
}

    function getCloseIngrdname($ingrdname,$localname)
{
    $this->load->database();
    $query = $this->db->get('onl_ingrd');
    foreach($query->result() as $row)
        $allingrd[]=$row->ingrd_name;

    foreach($localname as $row)
        $allingrd[]=$row;

            $shortest=-1;
            foreach ($allingrd as $ingrd) {
        $lev = levenshtein($ingrdname, $ingrd);
        if ($lev <= $shortest || $shortest < 0) {
            $closeword  = $ingrd;
            $shortest = $lev;

        }
    }
        return $closeword;
   }

Эта функция в контроллере

   function getResult()
   {
    $this->load->model('searchRecipe_model');
    $ingrdname = $this->input->post('ingrdname');
    $output[]=2;
    $localnames[]=$this->searchRecipe_model->getLocalIngrdname();
    $output[]=$this->searchRecipe_model->getCloseIngrdname($ingrdname,$localnames);
    echo json_encode($localnames); 
  }

$allingrd - это массив имен ингредиентов. Я отображаю $closeword в сообщении предупреждения JavaScript. Если я даю $lev=levenshtein($ingrdname,$allingrd[0]), это работает отлично; однако, это не работает в цикле. Есть идеи, почему? Заранее спасибо.

Ответы [ 3 ]

1 голос
/ 04 мая 2011

Может быть, у вас есть сом-строки, которые длиннее 255 символов?Функция levenshtein () возвращает -1 в этих случаях, что означает, что последняя такая строка всегда будет «самой короткой» в соответствии с вашим алгоритмом.Если это ваша проблема, вам нужно отбросить значения, где $ lev равен -1, следующим образом:

foreach ($allingrd as $ingrd) {
        $lev = levenshtein($ingrdname, $ingrd);
        if (($lev <= $shortest || $shortest < 0) && $lev != -1) {
            $closeword  = $ingrd;
            $shortest = $lev;

        }
}
return $closeword;

Обратите внимание, что $ closeword может быть не всегда установлен (если, например, все строки в$ allingrd длиннее 255 символов или если $ allingrd пусто).Не забудьте инициализировать $ closeword чем-то разумным перед циклом, например false, null или пустой строкой.

0 голосов
/ 04 мая 2011

Обратите внимание, что на странице PHP levenshtein они объявляют $shortest как -1.Это очень важно, иначе вы никогда не будете соответствовать требованиям оператора if.

$shortest = -1;
foreach ($allingrd as $ingrd) {
        $lev = levenshtein($ingrdname, $ingrd);
        if ($lev <= $shortest || $shortest < 0) {
            $closeword  = $ingrd;
            $shortest = $lev;

        }
}
return $closeword;

Это должно сработать.

0 голосов
/ 04 мая 2011

Я думаю, что вы пытаетесь сделать:

foreach ($allingrd as $ingrd) {
        $lev = levenshtein($ingrdname, $ingrd);
        if ($lev <= $shortest || $shortest < 0) {
            $closeword[] = $ingrd;
            $shortest[] = $lev;

        }
}
return $closeword;

Теперь $ closeword - это массив.Вы только что изменили значение $ closeword для каждого запуска цикла.Теперь вы выбросите значения внутри массива.То же самое для $ shorttest.

...