2進数字のパターンについて、2進ストリング・データの長いストリング(数メガバイトに相当する2進数字)を検索する必要があります。検索するパターンは約10万種類あります。それぞれ、1と0の最大10ビット/文字長のパターンです。次に、これらすべての最も一般的なパターンを表示する必要があります。
バイナリデータは、リアルタイムで何らかのテキストファイルまたはデータベースに送られます。基本的には2進数の大きなブロックであり、可能な限り最も効果的な方法で数千の異なるパターンを検索する必要があります。入ってくる新しい数字はそれぞれ、約10秒の時間で次々と現れます。
したがって、たとえば、次の文字列が入ってくる可能性があります。
10101110000110001011011111000101011010111101110100000011011101010101010111011100101010101011000101110011011111110001010010000110101011100000110011100101001010011001011010110101101010001010101010100010101010010100101001010101010111010101010010100101010011101010101010101001001010110101
0001100111
、0110011011
、1100011
など、これらの10万パターンの中から最も一般的なものを見つける必要があります。
テキストファイルに送られるリアルタイムデータでこれを行う最良の方法は何ですか?正確にリアルタイムである必要はありませんが、できるだけリアルタイムである必要があります。むしろ、レイテンシをできるだけなくすために、単なるコンソールの問題ですが、実際にターミナルである必要はないので、適応することもできます。
私はBashで約1年のプログラミング経験があります。単純なbashスクリプトは、100,000のそのようなパターンに対して十分高速でしょうか?しかし、これらの何千ものパターンすべては、単純なbashスクリプトソリューションだけでは少し遅すぎて時代遅れになるのではないかと恐れています。それとも、SQLは単なるbashスクリプトよりも本当に速いのでしょうか。バイナリマッチングアルゴリズムについて聞いたことがありますが、それらが何であるかは本当にわかりません。現時点では私のリーグから少し外れているようですが、それが本当に最も効果的な方法である場合、私は底まで進んでいきます。これを行うための最良の方法は何ですか?
再構成された問題ステートメント
巨大なバイナリcontent
があり、それをスキャンして数千ビットのセットpatterns
を探す必要があります。主な問題は、ビットパターンがバイトの先頭だけでなく、コンテンツの任意の場所で発生する可能性があることです。
アルゴリズム解
各パターンにid、初期ビットオフセット0、ビット長があり、最初のバイトの最上位ビットに配置された一連のバイトで定義されているとします。バイトのシーケンスは、さらに7ビットに対応するのに十分な長さである必要があります(例:_110110..-........
_。ここで、ポイントは、0に設定され、バイトの変更をダッシュするパターンバイトの未使用ビットを表します)。
各パターンについて、すべてのパターンのビットを1から7のオフセットでシフトすることで得られた7つの派生物を構築します(例:_.110110.-........
_、_..110110-........
_、_...11011-0.......
_など...)。それらの7つすべてと元のパターンをパターンIDへのmap
マッピングに保存します。
すべてのmap
アイテム:
content
のバイトオフセットごとに、残りのコンテンツの長さがパターンバイトの長さn
と比較して十分に長くなるようにします。
n
コンテンツバイトのコピーを作成し、コピーの最初のオフセットビットを0に設定します。8-((offset+bit length)%8)
最後のビットも0に設定します。
変更されたコピーをバイト単位でパターンと比較します。すべてのバイトが等しい場合は、マップされたパターンのカウントを増やします。
パターン数を減らしてパターンを並べ替える
文字列の場合と同様に、ステップ5はバイト比較によって行われるため、このアルゴリズムは非常に高速になります。ステップ4は、コピーに対する2つのバイナリAND演算に基づいているため、高速です。