文字列の実行を計算する


11

W. Rytterによる文字列の実行数から取られた以下の定義を考慮してください。単語、文字列、部分文字列はすべてほぼ同義語であることに注意してください。

文字列内の実行は、文字列内の拡張不可能な(同じ最小期間を持つ)定期的なセグメントです。

単語wの周期pは、この方程式の両側が定義されるたびにw [i] = w [i + p]となるような正の整数pです。per(w)がwの最小周期のサイズを示すものとします。per(w)<= | w | / 2の場合、単語wは周期的であると言います。

たとえば、文字列を考えますx = abcabper(abcab) = 3としてx[1] = x[1+3] = ax[2]=x[2+3] = bより短い期間はありません。abcabしたがって、文字列は周期的ではありません。ただし、文字列ababはper(abab)= 2のように周期的です。

文字列wの実行(または最大周期性)は、j> = iの区間[i ... j]です。

  • w [i ... j]は、周期p = per(w [i ... j])の周期的な単語です。
  • それは最大です。正式には、w [i-1] = w [i-1 + p]もw [j + 1] = w [j + 1-p]でもありません。非公式には、同じ期間のより大きな実行に実行を含めることはできません。

RUNS(w)によってwの実行セットを示します。

の4つの実行はatattatt、[4,5] = tt、[7,8] = tt、[1,4] = atat、[2,8] = tattattです。

文字列にaabaabaaaacaacacは、次の7つの実行が含まれます。

[1,2] = aa、[4,5] = aa、[7,10] = aaaa、[12,13] = aa、[13,16] = acac、[1,8] = aabaabaa、[9 、15] = aacaaca。

出力は、実行のリストになります。各実行では、それが表す間隔を指定する必要がありますが、部分文字列自体を出力する必要はありません。正確なフォーマットは、あなたにとって便利なものであれば何でもかまいません。

例では1インデックスを使用していますが、より便利な場合は、0インデックスを自由に使用できます。

仕事

文字列wを指定したコードを記述し、RUNS(w)を出力します。

言語と入力

任意の言語を使用して、最も便利な形式の入力文字列を取得できます。ただし、完全なプログラムを提供する必要があり、入力例で実行されているコードの例を示す必要があります。


4
いいチャレンジですが、デフォルトを無効にして機能を許可しない正当な理由はありますか?
マーティンエンダー

@MartinEnderそれは私の好みです。コードをコピーして貼り付けて自分で試してみるだけで簡単になり、より多くの人にとって答えがより面白くなります。

4
しかし、それはまた、多くのオーバーヘッドコードを引き起こし、冗長な構文を持つ言語の競争を不公平にします。私が書かなければならなかった場合、私は、例えばJavaでゴルフすることはないだろうclass A{public static ...}毎回私はゴルフのコードを望んでいた
Bassdrop Cumberwubwubwub

@BassdropCumberwubwubwub長所と短所があるのがわかります。私はたまたまプロをより強く評価します。たとえば、APLとPythonを比較するのではなく、類似の言語でゴルフの回答の長さを比較することは最も興味深いと思います。

「より大きなランに完全に含まれない場合、ランは最大になります」が、最初の例では、[7,8]は[2,8]に完全に含まれます。または、同じ部分文字列を繰り返す実行について厳密に話していますか?
SEがEVILであるため、aditsuは終了

回答:


2

Pyth、38バイト

{smm,hk+ekdfgaFTdcx1xM.ttB+0qVQ>QdZ2Sl

  m                                 SlQ   map for d in [1, …, len(input)]:
                            qVQ>Qd          pairwise equality of input[:-d] and input[d:]
                        tB+0                duplicate this list, prepending 0 to one copy
                      .t          Z         transpose, padding with 0
                    xM                      pairwise xor
                  x1                        find all occurrences of 1
                 c                 2        chop into groups of 2
           f                                filter for groups T such that:
             aFT                              the absolute difference between its elements
            g   d                             is greater than or equal to d
   m                                        map for groups k:
     hk                                       first element
    ,  +ekd                                   pair with the last element plus d
 s                                        concatenate
}                                         deduplicate

テストスイート


「[[3、5]、[6、8]、[0、4]、[1、8]]」を「attattatt」から取得します。[3,5]は「tt」を表しますか?使用したアルゴリズムについても高レベルで説明できれば素晴らしいと思います。

はい@Lembik、[i, j](0のインデックス)文字の間に開始スライスを表すi-1iし、文字の間に終了するj-1j。これは、Pythおよびほとんどの正気な言語の標準的な規則です(あるはずです)(ここここを参照)。
アンデルスカセオルグ16

すごい。ソリューションを直感的に説明することは可能ですか?残念ながら、コードの説明からリバースエンジニアリングを行うことはできません。

1
@Lembik期間dの実行を探しているとします。文字iが文字i + dと一致するすべての場所を見つけます。次に、少なくともd個の連続するそのような場所の実行を見つけます。すべてのdについて繰り返します。実際の期間はdの約数だけだった可能性があるため、最後に重複排除を行う必要があります。
アンデルスカセオルグ16

1

Cジャム、66

q:A,2m*{~A>_@)_@<2*@@2*<=},{_2$-2>2,.+={+}&}*]{[_1=\)\0=2*)+]}%_&p

オンラインで試す

簡単な説明:

アルゴリズムは4つのステップで動作します(最初の3つは、観察できる3つのメインブロックに対応しています)

  1. 重複した部分文字列(aba aba aaacaacacなど)に対応するすべての[長さインデックス]ペアを見つけます。これらは実行の一部です。
  2. 同じ実行、つまり連続したインデックスと同じ長さ/期間の一部であるペアを連結します。
  3. 最小インデックスと最大インデックス+ 2 *長さ-1を取得して、実際の実行を構築します。
  4. 最後に、重複した実行(異なる期間で取得された同じ間隔)を削除します

もっとゴルフをしたいので、これはすべて変更される可能性があります。


これありがとう。使用したアルゴリズムについて説明してください。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.