0

一連の長い数値 (等しい長さ) の配列 - 0101101111、0111101111、0101101101 など。

0101101001 に最も近い一致を検索

OK、それは短いバージョンです。長いバージョンは、11 のはい (1) といいえ (0) の質問 (製品検索) を含むフォームです。データベースには n^r の解 = 2048 と完全に一致するものがない可能性があることがわかっているため、最も近い一致を見つけるか、場合によっては最も近い 2 つまたは 3 つの一致を見つける必要があります。

各位置の各数値を比較して結果をランク付けする必要があると思いますが、正しい方向に進んでいる場合でも、解決策に行き詰まっています.

ありがとう!!

以下のポップヌードルの回答に対して簡単なチェックを行いました... using $lookslike=11100110011; foreachを実行し、SQLを生成し、phpMyAdminで6つの「回答」のテーブルに対して実行しました。

回答は次のようにランク付けされました。

答え -- ランク

11100110011 -- 11
11100110010 -- 10
11100110000 -- 9
00000111010 -- 6
00000111111 -- 6
01101100110 -- 6

*ランキングの説明のために編集 - 11 試合中 11 試合、11 試合中 10 試合、11 試合中 9 試合、11 試合中 6 試合...

非常に素晴らしい。

複数選択回答の変更された PHP マニュアルの例を追加しました。

<?php
// Client Answers
$input = 'abcdbcdabcd';

// array of answers to check against
$answers  = array('abcdbddabcd', 'abcbbcdabcd', 'abcdbcccccd');

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

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

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

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

        // closest word is this one (exact match)
        $closest = $answer;
        $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  = $answer;
        $shortest = $lev;
    }
}

echo "Input answer: $input\n" . "<br />";
if ($shortest == 0) {
    echo "Exact match found: $closest\n" . "<br />";
} else {
    echo "Possible Alternative: $closest?\n" . "<br />";
    echo "Levenshtein Distance: $lev\n";
}

?>

戻り値:

入力回答: abcdbcdabcd
考えられる代替案: abcbbcdabcd?
レーベンシュタイン距離: 3

4

3 に答える 3

0

私はSQLについてあまり知らないので、これはおそらく最も巧妙な方法ではありませんが、これまでのところ誰も貢献していません。

各位置の各文字を比較し、結果をランク付けします。

ランク=与えられた比較文字列「0101101001」の文字数が各行の回答の文字列と同じであるため(NBあなたは質問で11と言いましたが、例として10桁を与えました)

0101101001 against 0101101001 gives a rank of 10 
0101101001 against 1101101001 gives a rank of 9
0101101001 against 1111111001 gives a rank of 7
0101101001 against 0001100111 gives a rank of 6

SQLとして

SELECT answers,
    ( #looking for 0101101001
    IF (substring(answers,1,1)=0, 1, 0) 
    + IF (substring(answers,2,1)=1, 1, 0)
    + IF (substring(answers,3,1)=0, 1, 0)
    + IF (substring(answers,4,1)=1, 1, 0)
    + IF (substring(answers,5,1)=1, 1, 0)
    + IF (substring(answers,6,1)=0, 1, 0)
    + IF (substring(answers,7,1)=1, 1, 0)
    + IF (substring(answers,8,1)=0, 1, 0)
    + IF (substring(answers,9,1)=0, 1, 0)
    + IF (substring(answers,10,1)=1, 1, 0)
    ) 
AS rank
FROM yesno 
ORDER BY 
    ( #looking for 0101101001
    IF (substring(answers,1,1)=0, 1, 0) 
    + IF (substring(answers,2,1)=1, 1, 0)
    + IF (substring(answers,3,1)=0, 1, 0)
    + IF (substring(answers,4,1)=1, 1, 0)
    + IF (substring(answers,5,1)=1, 1, 0)
    + IF (substring(answers,6,1)=0, 1, 0)
    + IF (substring(answers,7,1)=1, 1, 0)
    + IF (substring(answers,8,1)=0, 1, 0)
    + IF (substring(answers,9,1)=0, 1, 0)
    + IF (substring(answers,10,1)=1, 1, 0)
    ) 
DESC

PHPとして

function getAnswers($lookslike)
{
    /* expects "binary" string
    returns the answers and rank (0 to string length) ordered by closest match first 
    */  

    foreach (str_split($lookslike) as $i=>$bit){
        $ifs[]='IF (substring(answers,' . ($i+1) . ',1)=' . $bit . ', 1, 0) ';
    }

    // use your db class
    return $db->select_many('
        SELECT answers,
            ( '. implode(' + ', $ifs) .' ) 
        AS rank
        FROM yesno 
        ORDER BY 
            ( '. implode(' + ', $ifs) .' ) 
        DESC
    ');
}

私のコードをチェックしていません

于 2013-01-04T19:57:54.743 に答える
0

あなたが探しているのは、レーベンシュタイン距離と呼ばれているようです。

かなり簡単で、どの言語でも実装するのは難しくありません。

MySQLで関数を実装する方法は次のとおりです

于 2013-01-07T02:18:26.463 に答える
0

情報をビットマスクとして整数フィールドに保存すると、いくつかのビット操作で同じ結果が得られると思います。

SELECT value 
FROM TABLE
ORDER BY BIT_COUNT(~(value ^ test)) DESC

test は、テストする値です。

たとえば、test が 11001 で value が 10101 の場合は次のようになります。

  • 11001 XOR 10101 = 01101
  • バイナリ反転 (~) = 10010
  • 1のビット数を数える ( BIT_COUNT) = 2
  • 並べ替えを逆にする

実際には、次のように短縮できると思います。

SELECT value 
FROM TABLE
ORDER BY BIT_COUNT(value ^ test)

これは本質的に異なるビットをカウントしているため、昇順ソートは必要なものを返す必要があります。

于 2013-01-07T02:46:28.867 に答える