サイズが 30のセットのunsigned long
場合、次の方法がかなり明白な方法の 1 つです。
- 各セットを並べ替えられた配列として格納し
30 * sizeof(unsigned long)
ます (セットごとのバイト数)。
- 整数を検索するには、二分探索を数ステップ実行し、続いて線形探索を実行します (二分探索の最適なステップ数を把握するためのプロファイル - 私の勝手な推測では 2 ステップですが、異なることがわかるかもしれません。もちろん、テスト
bsearch
して十分に速い場合は、そのまま使用できます)。
したがって、次の質問は、なぜ大規模なソリューションが必要なのかということです。これにより、「十分に満足できない」以外に、このソリューションの何が問題なのかがわかります。
大きな数学のソリューションは、これよりも遅くなると思います。N 桁の数値に対する単一の算術演算は、少なくとも N の線形時間かかります。セットを表す単一の数値は、区切り文字を挟んで端から端まで配置されたセットの要素よりもはるかに小さくすることはできません。したがって、セット内の線形検索でさえ、大きな数に対する単一の算術演算とほぼ同じくらい高速です。n
ゲーデル表現の可能性のある例外を除いて、1番目の素数が見つかったら 1 つの除算でそれを行うことができますが、セットの巧妙な数学的表現は、メンバーシップを確立するために複数の算術演算を必要とします。
また、「セット内の整数を検索する」のパフォーマンスを気にする理由は 2 つあります。
- 1 つのセットで多数の異なる整数を検索しています。この場合、そのデータのカスタム ルックアップ関数を作成することで高速化できる場合があります。もちろん、C では、(a) その「関数」を実行する単純な仮想マシン、(b) ランタイム コード生成、または (c) コンパイル時にセットを知る必要があることを意味します。どれも必ずしも簡単ではありません。
- 多くの異なるセットで同じ整数を検索しています (それが属するすべてのセットのシーケンスを取得するため)。 .
非常にまれに、それぞれが異なるセットにある多くの異なる整数を検索している可能性があるため、どちらの理由にも当てはまらないと思います。これがそれらの 1 つである場合は、そのようなものを無視できます。