Oli Charlesworth の言うことに従って、基数b
を特定の除数d
で割り切れるように DFA を構築できます。DFA の状態は除算の残りを表します。
あなたの場合(基数2 - 2進数、除数d
= 3 10):
上記の DFA は、空の文字列を 3 で割り切れる「数値」として受け入れることに注意してください。これは、前にもう 1 つの中間状態を追加することで簡単に修正できます。
理論上の正規表現への変換は、通常のプロセスで実行できます。
再帰正規表現をサポートするフレーバーでの実用的な正規表現への変換は、DFA があれば簡単に行うことができます。これは、CodeGolf.SE からのこの質問の (base b
= 10, d
= 7 10 )の場合に示されています。
Ruby regex フレーバーで書かれた Lowjacker による回答の正規表現を引用させてください。
(?!$)(?>(|(?<B>4\g<A>|5\g<B>|6\g<C>|[07]\g<D>|[18]\g<E>|[29]\g<F>|3\g<G>))(|(?<C>[18]\g<A>|[29]\g<B>|3\g<C>|4\g<D>|5\g<E>|6\g<F>|[07]\g<G>))(|(?<D>5\g<A>|6\g<B>|[07]\g<C>|[18]\g<D>|[29]\g<E>|3\g<F>|4\g<G>))(|(?<E>[29]\g<A>|3\g<B>|4\g<C>|5\g<D>|6\g<E>|[07]\g<F>|[18]\g<G>))(|(?<F>6\g<A>|[07]\g<B>|[18]\g<C>|[29]\g<D>|3\g<E>|4\g<F>|5\g<G>))(|(?<G>3\g<A>|4\g<B>|5\g<C>|6\g<D>|[07]\g<E>|[18]\g<F>|[29]\g<G>)))(?<A>$|[07]\g<A>|[18]\g<B>|[29]\g<C>|3\g<D>|4\g<E>|5\g<F>|6\g<G>)
分解すると、それがどのように構築されているかがわかります。アトミックグループ (または非バックトラッキンググループ、または所有的に動作するグループ) は、空の文字列の代替のみが一致することを確認するために使用されます。(?DEFINE)
これは、 Perlでエミュレートするためのトリックです。そして、その数を7で割ったときの余り0~6に対応するA
グループ。G
(?!$)
(?>
(|(?<B>4 \g<A>|5 \g<B>|6 \g<C>|[07]\g<D>|[18]\g<E>|[29]\g<F>|3 \g<G>))
(|(?<C>[18]\g<A>|[29]\g<B>|3 \g<C>|4 \g<D>|5 \g<E>|6 \g<F>|[07]\g<G>))
(|(?<D>5 \g<A>|6 \g<B>|[07]\g<C>|[18]\g<D>|[29]\g<E>|3 \g<F>|4 \g<G>))
(|(?<E>[29]\g<A>|3 \g<B>|4 \g<C>|5 \g<D>|6 \g<E>|[07]\g<F>|[18]\g<G>))
(|(?<F>6 \g<A>|[07]\g<B>|[18]\g<C>|[29]\g<D>|3 \g<E>|4 \g<F>|5 \g<G>))
(|(?<G>3 \g<A>|4 \g<B>|5 \g<C>|6 \g<D>|[07]\g<E>|[18]\g<F>|[29]\g<G>))
)
(?<A>$| [07]\g<A>|[18]\g<B>|[29]\g<C>|3 \g<D>|4 \g<E>|5 \g<F>|6 \g<G>)