自然なシーケンスインデックスがありますが、計算はそれほど簡単ではありません。
A_0 = 1なので、n>0のA_nを探しましょう。
インデックス作成は2つのステップで行われます。
パート1:
A_n = max(A_0 .. A_n-1)+1の場所でシーケンスをグループ化します。これらの場所をステップと呼びます。
- ステップには連続した番号(2、3、4、5、...)があります。
- ステップ以外の場所では、1からインデックスがk未満のステップ数までの数値を入力できます。
各グループは、1がステップ、0が非ステップのバイナリ文字列として表すことができます。たとえば、001001010は、112aa3b4c、a <= 2、b <= 3、c<=4のグループを意味します。グループは2進数でインデックス付けされるため、グループの自然なインデックス付けがあります。0から2^length-1まで。グループバイナリ表現の値をグループ順序で呼び出します。
パート2:
グループ内のインデックスシーケンス。グループはステップ位置を定義するため、非ステップ位置の数値のみが可変であり、定義された範囲で可変です。これにより、さまざまな場所の辞書式順序を使用して、そのグループ内の特定のグループのシーケンスにインデックスを付けることが簡単になります。
1つのグループのシーケンス数を計算するのは簡単です。フォーム1^i_1 * 2 ^ i_2 * 3 ^ i_3*...の番号です。
組み合わせる:
これにより、2つの部分からなるキーが得られ<Steps, Group>
ます。次に、これを整数にマップする必要があります。そのためには、ある値よりも小さい順序を持つグループ内のシーケンスの数を見つける必要があります。そのために、最初に、指定された長さのグループに含まれるシーケンスの数を見つけましょう。これは、すべてのグループを通過し、シーケンスの数などを繰り返して合計することで計算できます。T(l、n)を長さl(A_0は省略)のシーケンスの数とします。ここで、最初の要素の最大値はn+1になります。保持するより:
T(l,n) = n*T(l-1,n) + T(l-1,n+1)
T(1,n) = n
l + n <= sequence length + 1
〜T(l、n)の値があるためsequence_length^2/2
、簡単に計算できます。
次に、与えられた値以下の順序のグループでシーケンスの数を計算します。これは、T(l、n)値を合計することで実行できます。たとえば、順序が1001010バイナリ未満のグループ内のシーケンスの数は、次のようになります。
T(7,1) + # for 1000000
2^2 * T(4,2) + # for 001000
2^2 * 3 * T(2,3) # for 010
最適化:
これによりマッピングが得られますが、主要部分を組み合わせるための直接実装は>O(1)
せいぜいです。一方、Steps
キーの部分は小さく、Groups
各Steps
値の範囲を計算することにより、ルックアップテーブルはこれをに減らすことができますO(1)
。
上位の数式については100%確信が持てませんが、そのようなものになるはずです。
これらの発言と再発により、関数をシーケンス->インデックスおよびインデックス->シーケンスにすることができます。しかし、それほど些細なことではありません:-)