1. 問題の定義
文字列全体が pattern に一致しない場合に何を出力するかがK*
明確でないため、そのような場合に何を出力するかを明確にするために問題を再定義します。
任意のパターン K が与えられた場合:
- 文字列にパターンがあることを確認します
K*
。
- 文字列に pattern がある場合は
K*
、一致する重複しないトークンに文字列を分割しますK
。
- 文字列に pattern に一致するプレフィックスしかない場合は、 1
K*
によって選択されたプレフィックスを選択し、プレフィックスを K に一致するトークンに分割します。K*+
1とにかく K に一致する最長のプレフィックスを取得する方法があるかどうかはわかりません。もちろん、最後の文字を 1 つずつ削除して、K*
一致するまでテストすることはいつでもできますが、明らかに非効率的です。
特に明記しない限り、以下に記載するものはすべて、上記の問題の説明に従います。問題の 3 番目の箇条書きは、どのプレフィックス文字列を使用するかについてのあいまいさを解決することです。
2. .NET で繰り返しキャプチャ グループ
上記の問題は、問題の解決策があれば解決できます。
(K)*
繰り返されるキャプチャ グループであるpatternを指定すると、最後の繰り返しだけでなく、すべての繰り返しについてキャプチャされたテキストを取得します。
- 文字列に pattern がある場合、
K*
と照合することで^(K)*$
、 pattern に一致するすべてのトークンを取得できますK
。
- 文字列が に一致するプレフィックスのみを含む場合、 と
K*
照合することで^(K)*
、 pattern に一致するすべてのトークンを取得できますK
。
これは .NET 正規表現の場合に当てはまります。これは、繰り返されるキャプチャ グループのすべてのキャプチャされたテキストを保持するためです。
ただし、Java を使用しているため、そのような機能にはアクセスできません。
3. Java での解決策
文字列がパターンK*
を持っていることの確認は、常にMatcher.matches()
/String.matches()
で行うことができます。これは、エンジンが入力文字列に対して本格的なバックトラックを実行して、何らかの方法で入力文字列と「統合」するためK*
です。難しいのは、入力文字列を pattern に一致するトークンに分割することですK
。
K*
と同等の場合K*+
パターン K に次のプロパティがある場合:
すべての文字列に対して2はK*
と同等ですK*+
。つまり、入力文字列が pattern に一致するトークンに分割される方法はK
同じです。
2この条件は、操作している入力文字列に対してのみ定義できますが、この前提条件を確保するのは簡単ではありません。すべての文字列に対して定義すると、正規表現を分析して条件が成立するかどうかを確認するだけで済みます。
その後、問題を解決するワンパス ソリューションを構築できます。Matcher.find()
patternで繰り返し使用でき\GK
、見つかった最後の一致が文字列の末尾にあることを確認します。これは、コードで境界チェックを行うことを除いて、現在のソリューションに似ています。
inの量指定子の+
後は、量指定子を所有格にします。所有量指定子は、エンジンがバックトラックするのを防ぎます。これは、各繰り返しが常にパターン K の最初の可能な一致であることを意味します。パターン K の最初の可能な一致も返すため、ソリューションが同等の意味を持つようにするために、このプロパティが必要です。*
K*+
\GK
K*
同等でない場合K*+
上記のプロパティがなければ、問題を解決するには 2 つのパスが必要です。pattern でMatcher.matches()
/を呼び出すための最初のパス。2 回目のパス:String.matches()
K*
文字列が pattern に一致しない場合は、一致するものが見つからなくなるまでパターンでK*
繰り返し使用します。これは、入力文字列が pattern に一致しない場合にどのプレフィックス文字列を使用するかを定義する方法により実行できます。Matcher.find()
\GK
K*
文字列が pattern に一致する場合、 patternK*
で繰り返し使用Matcher.find()
すること\GK(?=K*$)
が 1 つの解決策です。ただし、これにより、残りの入力文字列と一致する冗長な作業が発生します。
この解は任意の K に普遍的に適用可能であることに注意してください。つまり、 がK*
と等しい場合にも適用されますK*+
(ただし、代わりに、より優れたワンパス ソリューションを使用します)。