2012-04-15 9 views
0

私はユーザーが会社の名前を入力するためのインターフェースを持っています。次に、入力した内容とデータベース内の現在の項目を比較し、似たようなものが見つかった場合はオプションを提示します(スペルが間違っている場合)。または、入力内容を確認するボタンをクリックすることができます。類似した文字列を確実に見つける方法

私が抱えている問題は、それがあまり正確ではなく、よく似ていない何十もの「類似の」マッチをもたらしていることです!

ここに私が今いるのは、私が作っていない最初の大規模な機能であり、正確には何かを明確にしていません。私が欲しいものを手に入れるための方法はずっと簡単ですか?

// Compares strings and determines how similar they are based on a nth letter split  comparison. 
function cmp_by_optionNumber($b, $a) { 
if ($a["score"] == $b["score"]) return 0; 
if ($a["score"] > $b["score"]) return 1; 
return -1; 
} 
function string_compare($str_a, $str_b) 
{ 
$length = strlen($str_a); 
$length_b = strlen($str_b); 

$i = 0; 
$segmentcount = 0; 
$segmentsinfo = array(); 
$segment = ''; 
while ($i < $length) 
{ 
    $char = substr($str_a, $i, 1); 
    if (strpos($str_b, $char) !== FALSE) 
    { 
     $segment = $segment.$char; 
     if (strpos($str_b, $segment) !== FALSE) 
     { 
      $segmentpos_a = $i - strlen($segment) + 1; 
      $segmentpos_b = strpos($str_b, $segment); 
      $positiondiff = abs($segmentpos_a - $segmentpos_b); 
      $posfactor = ($length - $positiondiff)/$length_b; // <-- ? 
      $lengthfactor = strlen($segment)/$length; 
      $segmentsinfo[$segmentcount] = array('segment' => $segment, 'score' => ($posfactor * $lengthfactor)); 
     } 
     else 
     { 
      $segment = ''; 
      $i--; 
      $segmentcount++; 
     } 
    } 
    else 
    { 
     $segment = ''; 
     $segmentcount++; 
    } 
    $i++; 
} 

// PHP 5.3 lambda in array_map 
$totalscore = array_sum(array_map(function($v) { return $v['score']; }, $segmentsinfo)); 
return $totalscore; 
} 

$q = $_POST['stringA'] ; 
$qLengthMin = strlen($q) - 5 ; // Part of search calibration. Smaller number = stricter. 
$qLengthMax = strlen($q) + 2 ; // not in use. 

$main = array() ; 

include("pdoconnect.php") ; 

$result = $dbh->query("SELECT id, name FROM entity_details WHERE 
        name LIKE '{$q[0]}%' 
        AND CHAR_LENGTH(name) >= '$qLengthMin' 
        #LIMIT 50") ; // The first letter MUST be correct.  This assumption makes checker faster and reduces irrelivant results. 
$x = 0 ; 
while($row = $result->fetch(PDO::FETCH_ASSOC)) { 

$percent = string_compare(strtolower($q), strtolower(rawurldecode($row['name']))) ; 

if($percent == 1) { 
    //echo 1 ;// 1 signifies an exact match on a company already in our DB. 
    echo $row['id'] ; 
    exit() ; 
} 
elseif($percent >= 0.6) { // Part of search calibration. Higher deci number = stricter. 
    $x++ ; 
    $main[$x]['name'] = rawurldecode($row['name']) ; 
    $main[$x]['score'] = round($percent, 2) * 100; 

    //array_push($overs, urldecode($row['name']) . " ($percent)<br />") ; 
} 

} 

usort($main, "cmp_by_optionNumber") ; 
$z = 0 ; 
echo '<div style="overflow-y:scroll;height:175px;width:460px;">' ; 
foreach($main as $c) { 
if($c['score'] > 100) $c['score'] = 100 ; 
if(count($main) > 1) { 
echo '<div id="anysuggested' . $z . '" class="hoverdiv" onclick="selectAuto(' . "'score$z'" . ');">' ; 
} 
else echo '<div id="anysuggested' . $z . '" class="hoverdiv" style="color:#009444;" onclick="selectAuto(' . "'score$z'" . ');">' ; 
echo '<span id="autoscore' . $z . '">' . $c['name'] . '</span></div>' ; 
$z++ ; 
} 
echo '</div>' ; 

答えて

関連する問題