2012-04-10 11 views
2

私は3から20文字の単語のデータベースを持っています。私は、より大きな単語の中に含まれている小さな単語のすべてを見つけるPHPのコードを作成したいと思います。たとえば、「内向き」という単語には「雨」、「勝利」、「除外」などの単語があります。パズル解決:PHPの大きな単語内のすべての単語を見つける

最初に、単語表にフィールドを追加することを考えました(Words3〜Words20、例えば、 "rally"は10000000000200000100000010:文字Aのインスタンス1、文字Bのインスタンス0、...のように表現されます。文字の2つのインスタンス次に、各テーブルのすべての単語(または見つかった単語のターゲットの長さが指定されている場合は1つのテーブル)を調べ、各単語のLetterCountをソース単語のLetterCountと比較します(上記の例では "内側" )。

しかし、私はそれがMySQLデータベースとPHPスクリプトに負荷をかけることになり、各単語のLetterCountを呼び出し、それぞれの桁をソース単語のそれと比較するなどの作業を開始しました。

これを行うのが簡単で、おそらく直感的な方法はありますか?どのような方法でもオーバヘッドを助けるならば、私はストアドプロシージャを使うことに慣れています。ちょうどいくつかの提案は非常に高く評価されるだろう。ありがとう!

答えて

6

これは非常に効率的であるはずですが、特定のサイズの単語(おそらく15-20文字程度で、単語を構成する文字が低周波低い値の文字または高い値の高頻度の文字):

  1. 各文字には、その頻度に従って素数を割り当てます。したがって、hereまたは類似のソースからの周波数値を使用して、eは2、t = 3、a = 5などです。
  2. 単語リストの各単語の値を計算します。単語の文字の素数を掛けて、テーブルのbigintデータ型列に格納します。たとえば、teaの値は3*2*5=30です。単語に繰り返し文字が含まれている場合は、teatの値が3*2*5*3=90になるように係数を繰り返します。
  3. rainなどの単語がinwardなどの別の単語の中に含まれているかどうかを確認する場合は、rainの値がinwardの値を分けるかどうかを確認するだけで十分です。この場合、inward = 14213045,rain = 7315および142130457315で割り切れるので、rainという語はinwardという語の中にあります。
  4. bigint列は、9223372036854775807になります。これは、単語の文字の頻度に応じて、約15〜20文字までは問題ありません。たとえば、hereから最初の20文字の単語(anitinstitutionalism)を取得しました。値は6901041299724096525で、bigint列の中にはほとんど収まりません。ただし、14文字の単語xylopyrographyの値は635285791503081662905であり、大きすぎます。本当に大きなものを別の方法で特殊なケースとして扱う必要があるかもしれませんが、そのほうがまだ効率的であるとは思えないほどです。

クエリは、私がここに用意しましたデモのようなものに動作します:http://www.sqlfiddle.com/#!2/9bd27/8

+0

+1非常に素晴らしいが... – dqhendricks

+0

これは素晴らしいです!データベースの20文字の単語のうちいくつかを試して平均プライムプロダクトが何であるかを調べることができると思います。しかし、これはこれを行うことについて行くための素晴らしい方法のように見えます。 – TerranRich

+1

これを20文字に拡大する方法の1つは、単語の値を1番目、3番目、5番目、7番目の文字などの2つの部分に分割することです。つまり、 'e、a、n、s、...' 2番目、4番目、6番目、8番目の文字等、すなわち 't、i、o、r、... 'のためのものです。次に、マスター単語の 'value1'がリストの単語の' value1'で割り切れるかチェックし、マスター単語の 'value2'がリストの単語の' value2'で割り切れるかどうかをチェックします。 2つの数字に分割すると、すべての単語がbigintの範囲に収まる可能性が非常に高いという点を除いて、アイデアは同じです。 – mellamokb

関連する問題