アルファベット 上の正規表現
を考え、 が表す言語を とする( は和集合、 はクリーネ閉包を表す)。 に属する長さ の文字列の個数を求めよ。
正規言語に属する長さ n の文字列の数え上げ
のような正規表現の言語に属する文字列をブロックへの分解(またはオートマトンへの変換)で漸化式に直し、 の個数の偶奇などの条件も状態に加えて、長さ の文字列の個数を求められる
前提
- 正規表現が表す言語と文字列の判定 (大学数学 オートマトン・形式言語)
- 状態ごとの文字列数の漸化式 (大学数学 オートマトン・形式言語)
この技能までの道筋(6 技能)
読み込み中…
右端(太枠)がこの技能です。左へドラッグすると、さらに前の前提をさかのぼれます。技能を押すと、そこまでの道筋が光ります。
一覧で見る(前提が先)
- 正規表現が表す言語と文字列の判定 (大学数学 オートマトン・形式言語)
- 決定性有限オートマトンの動作と受理判定 (大学数学 オートマトン・形式言語)
- 樹形図で数え上げる (算数 場合の数)
- 積の法則と和の法則 (算数 場合の数)
- 和の法則・積の法則と樹形図 (数学A 場合の数と確率)
- 状態ごとの文字列数の漸化式 (大学数学 オートマトン・形式言語)
説明
正規表現で表された言語について、長さ の文字列がいくつあるかを数える方法を学びます。文字列を決まった形のブロックに切り分けて「最後のブロックが何か」で場合分けすると、個数の漸化式が得られます。さらに「 の個数が偶数」のような条件は、偶数・奇数の 2 つの状態に分けて数えれば同じ方法で扱えます。符号の数え上げや、パターンを避ける文字列の個数などでよく使います。
なぜそうしてよいのか
例として を考えます。この言語の文字列は、ブロック を何個か(0 個でもよい)つないだものです。どのブロックも で始まり、 はブロックの先頭にしか現れません。そのため、 の文字列は「各 の直前で切る」以外の切り方ができず、ブロックへの分け方はただ 1 通りに決まります。分け方が 1 通りなので、「文字列を 1 つ数える」ことと「ブロックの並びを 1 つ数える」ことが同じになります。
長さ の文字列の個数を とします。 のとき、最後のブロックは (長さ 1)、(長さ 2)、(長さ 3)のどれかで、この 3 つの場合は重なりません。最後のブロックを取り除いた残りは、長さ の の文字列で、どれでもよいです。和の法則から となります。ただし (空文字列 1 個)、負の長さについては とします。これは、ブロックの区切り目を状態とする DFA で、前提の技能の更新式 を使うことを、ブロック単位にまとめて行っているのと同じです。
「 の個数が偶数」という条件を加えるときは、 が偶数個の文字列の個数 と奇数個の個数 を別々に数えます。最後のブロックを付け足すと、そのブロックに含まれる の個数の偶奇だけ偶奇が変わります。 は を 0 個含むので偶奇は変わりません。 は 1 個含むので偶奇が反転します。 は 2 個含むので偶奇は変わりません。これは DFA に「偶奇」という状態を付け加えて、状態ごとに数えることにあたります。
手順
文字列がブロックに一通りに分解できることを確かめる。一通りにならないときや分解が難しいときは、言語を受理する DFA を作り、状態ごとの漸化式に切り替える。
長さ の個数を とおき、最後のブロックで場合分けする。ブロックの長さが のとき とする。初期値は 、負の長さでは とする。
偶奇などの追加条件があるときは、状態ごとの個数(例: )に分ける。各ブロックがどの状態をどの状態に移すかを調べて、状態ごとの漸化式を立てる。
から順に表で計算し、条件を満たす状態の値を答えにする。検算として、全状態の和が条件なしの に一致するかを確かめる。
例題
アルファベット 上の正規表現 の言語に属する長さ の文字列のうち、 の個数が偶数であるものの個数を求めよ。
例題の解答
手順1: どのブロック も で始まり、 は先頭にしか現れません。したがって各 の直前で切る分け方しかなく、分解は一通りに決まります。
手順2: 長さ の文字列の総数 は 、 を満たします(検算に使います)。
手順3: が偶数個のものの個数を 、奇数個のものの個数を とします。 と は偶奇を変えず、 は偶奇を反転させます。よって
です。初期値は (空文字列は が 0 個)、負の添字の値は とします。
手順4: 順に計算します。
- :
- : ( と に対応)
- :
- :
- :
- :
検算: は と進みます。各 で が成り立ち、 では です。
よって求める個数は です。
答え:
よくある誤り
分解が一通りでないのに、ブロックの並べ方を数えてしまう誤り。例えば で とすると、 になります。正しくは が とも分けられるので、言語は 上のすべての文字列で、()です。分解が一通りでないときは DFA を作って数えます。
初期値を としてしまう誤り。正しくは、空文字列は に属するので です。 にすると、 のように全部が 0 になってしまいます。
ブロックが偶奇に与える影響を取り違える誤り。例えば で偶奇が反転するとして とするのは誤りです。正しくは、 は を 2 個含むので偶奇は変わらず、 です。
追加条件の状態の更新で、移る前と後の状態を逆にしてしまう誤り。 を付けて偶数になるのは、付ける前が奇数のものなので、正しくは の式に が入ります( ではありません)。
この説明は AI が書き、別の AI が例題を独立に解いて答えを確かめ、説明を一歩ずつ査読しました。
入口の問題
アルファベット 上の正規表現
を考え、 が表す言語を とします( は和集合、 はクリーネ閉包を表し、空列も に含まれます)。長さ の文字列のうち、 に属するものの個数を求めなさい。アルファベット 上の正規表現
を考え、 が表す言語を とします( は和集合、 はクリーネ閉包を表します)。 に属する長さ の文字列の個数を求めなさい。