[この質問は、文字列の実行を計算するためのフォローアップです]
期間
p
文字列はw
任意の正の整数であるp
ようなw[i]=w[i+p]
ときはいつでも、この式の両辺が定義されています。per(w)
の最小周期のサイズを示しましょうw
。文字列w
は周期的であると言うper(w) <= |w|/2
。
したがって、非公式には、定期的な文字列は、少なくとも1回繰り返される別の文字列から構成される単なる文字列です。唯一の問題は、文字列の最後で、少なくとも1回全体が繰り返される限り、繰り返される文字列の完全なコピーを必要としないことです。
たとえば、文字列を考えますx = abcab
。per(abcab) = 3
としてx[1] = x[1+3] = a
、x[2]=x[2+3] = b
より短い期間はありません。abcab
したがって、文字列は周期的ではありません。ただし、文字列ababa
はとして周期的per(ababa) = 2
です。
より多くの例としては、abcabca
、ababababa
とabcabcabc
も周期的です。
正規表現が好きな人のために、これは文字列が周期的かどうかを検出します:
\b(\w*)(\w+\1)\2+\b
タスクは、より長い文字列内のすべての最大周期部分文字列を見つけることです。これらは文献ではランと呼ばれることもあります。
部分文字列
w
は、周期的であり、w[i-1] = w[i-1+p]
でもない場合、最大の周期的部分文字列(実行)ですw[j+1] = w[j+1-p]
。非公式には、同じ期間のより大きな「実行」に「実行」を含めることはできません。
2回の実行は、文字列全体の異なる場所で発生する同じ文字列を表すことができるため、実行を間隔で表します。上記の定義を間隔で繰り返します。
文字列内のラン(又は最大周期サブストリング)が
T
間隔である[i...j]
とj>=i
、このような、
T[i...j]
周期のある周期的な単語ですp = per(T[i...j])
- それは最大です。正式には、
T[i-1] = T[i-1+p]
でもありませんT[j+1] = T[j+1-p]
。非公式には、同じ期間のより大きな実行に実行を含めることはできません。
表すRUNS(T)
文字列の実行のセットT
。
実行の例
文字列の4つの最大の周期ストリング(実行)が
T = atattatt
ありT[4,5] = tt
、T[7,8] = tt
、T[1,4] = atat
、T[2,8] = tattatt
。文字列は
T = aabaabaaaacaacac
、以下の7つの最大の定期的なストリング(実行)を含んでいますT[1,2] = aa
、T[4,5] = aa
、T[7,10] = aaaa
、T[12,13] = aa
、T[13,16] = acac
、T[1,8] = aabaabaa
、T[9,15] = aacaaca
。文字列に
T = atatbatatb
は、次の3つの実行が含まれます。彼らは以下の通りですT[1, 4] = atat
、T[6, 9] = atat
とT[1, 10] = atatbatatb
。
ここでは、1-indexingを使用しています。
タスク
2から始まる整数nごとに、lengthの任意のバイナリ文字列に含まれる実行の最大数を出力するようにコードを記述しますn
。
スコア
あなたのスコアはn
120秒で到達する最高値であり、すべてk <= n
の人にとって、あなたよりも高い正解を誰も投稿していない。明らかに、すべての最適な回答があれば、n
投稿した最高のスコアが得られます。ただし、あなたの答えが最適でなくても、他の誰もそれを打つことができなければ、あなたはまだスコアを得ることができます。
言語とライブラリ
使用可能な任意の言語とライブラリを使用できます。可能であれば、コードを実行できるとよいので、可能な限りLinuxでコードを実行/コンパイルする方法の完全な説明を含めてください。
最適例
以下では:n, optimum number of runs, example string
。
2 1 00
3 1 000
4 2 0011
5 2 00011
6 3 001001
7 4 0010011
8 5 00110011
9 5 000110011
10 6 0010011001
11 7 00100110011
12 8 001001100100
13 8 0001001100100
14 10 00100110010011
15 10 000100110010011
16 11 0010011001001100
17 12 00100101101001011
18 13 001001100100110011
19 14 0010011001001100100
20 15 00101001011010010100
21 15 000101001011010010100
22 16 0010010100101101001011
コードは何を正確に出力する必要がありますか?
n
コードごとに、単一の文字列とそれに含まれる実行回数を出力する必要があります。
私のマシンタイミングは私のマシンで実行されます。これは、AMD FX-8350 8コアプロセッサへの標準のUbuntuインストールです。これは、コードを実行できる必要があることも意味します。
主要な回答
- 49 Cの Anders Kaseorgによる。シングルスレッドで、L = 12(2GBのRAM)で実行します。
- Cの cdlaneによる27。
{0,1}
-strings のみを考慮したい場合は、明示的に述べてください。そうしないと、アルファベットが無限になる可能性があり、{0,1}
文字列のみを検索したように見えるため、テストケースが最適である理由がわかりません。
n
最大3文字のアルファベットで文字列を検索しました12
が、バイナリアルファベットに勝るものはありませんでした。ヒューリスティックには、文字を追加すると実行の最小長が長くなるため、バイナリ文字列が最適であると予想されます。