1

私は MySQL とクエリを学習している最中であり、現在は PHP を使用して作業を開始しています。学習目的で、最初に小さなアナグラム ソルバーのようなプロジェクトを選びました。インターネット上で、DBとして無料で利用できる非常に古い英語の単語リストを見つけました。クエリ、セット内検索、全文検索マッチングを試みましたが失敗しました。

どうやって:

結果を文字ごとに一致させますか?

たとえば、データベース エントリと照合する文字 SLAOG があるとします。

確かに多くの単語を含む大規模なデータベースがあるため、クエリの代わりに次のようにします。

lag
goal
goals
slag
log
... and so on.

文字が2回使用される可能性のある他の結果はありません。

これをSQLでどのように解決しますか?

どうぞよろしくお願いいたします。

4

3 に答える 3

1

迅速で汚い解決策が必要な場合...

アナグラムを取得しようとしている単語を個々の文字に分割します。各文字に個別の素数値を割り当て、それらをすべて一緒に乗算します。例えば:

C - 2
A - 3
T - 5

合計30

次に、辞書リストをステップ実行し、その中の各単語に対して同じ操作を実行します。ターゲット単語の値が辞書単語の値で正確に割り切れる場合、辞書単語にはターゲット単語に出現する文字のみが含まれていることがわかります。

辞書の値を事前に計算してから、適切な値をクエリすることで、速度を上げることができます。SELECT * FROM dictionary WHERE($ searchWordTotal%wordTotal)= 0(searchWordTotalは、探している単語の合計であり、 wordTotalはデータベースからのものです)

私は最近、これを適切に書くことに取り掛かる必要があります。

于 2012-05-11T14:47:28.807 に答える
1
$str_search = 'SLAOG';

SELECT word
FROM table_name
WHERE word REGEXP '^[{$str_search}]+$' # '^[SLAOG]+$'

// Filter the results in php afterwards

// Loop START

$arr = array();
for($i = 0; $i < strlen($row->word); $i++) {

    $h = substr($str_search, $i, 0);
    preg_match_all("/{$h}/", $row->word, $arr_matches);
    preg_match_all("/{$h}/", $str_search, $arr_matches2);

    if (count($arr_matches[0]) > count($arr_matches2[0]))
        FALSE; // Amount doesn't add up

}

// Loop END

基本的に、指定された単語に対して REGEXP を実行し、検索単語と比較した単語の出現回数に基づいて結果をフィルタリングします。

REGEXP は、指定された単語の組み合わせを使用して、最初から最後まですべての列をチェックします。これにより、必要以上の行が生成される可能性がありますが、それでも適切なフィルターが得られます。

ループ部分は、文字が検索文字列よりも多く使用されている単語をフィルタリングすることです。preg_match_all()見つかった単語と検索単語の各文字に対してa を実行して、出現回数を確認し、それらを と比較しますcount()

于 2012-05-11T12:58:12.087 に答える
0

指定された文字の単語のみが必要で、他の文字は必要ないため、すべての文字を使用する必要はないため、次のようなロジックを提案します。

* take your candidate word,
* do a string replace of the first occurrence of each letter in your match set,
* set the new value to null
* then finally wrap all that in a strlength to see if there are any characters left.

これらはすべて sql で実行できますが、ほとんどのコーダーには、おそらく少しの手順の方がなじみがあるように見えるでしょう。

于 2012-05-11T12:56:13.363 に答える