设计DFA接受可被数字'n'整除的二进制字符串

时间:2014-02-20 03:35:14

标签: regex automata dfa

我需要学习如何设计DFA,以便给定任意数字'n',它接受二进制字符串{0,1},其十进制等效数可以被'n'整除。

不同的'n'会有不同的DFA,但是有人可以提供一个基本的方法,我应该遵循以继续任何数字0< n< 10。

2 个答案:

答案 0 :(得分:5)

我知道我已经很晚了,但我只想在@Grijesh提供的正确答案中添加一些内容。我想指出@Grijesh提供的答案不会产生最小的DFA。虽然答案肯定是获得DFA的正确方法,但如果你需要最小的DFA,你将需要调查你的除数。

例如,在二进制数中,如果除数是2的幂(即2 ^ n),则所需的最小状态数将是n + 1。你会如何设计这样的自动机?只需查看二进制数的属性即可。对于一个数字,比如说8(即2 ^ 3),它的所有倍数都将最后3位作为0.例如,二进制中的40是101000.因此,对于一种语言来接受任何可被8整除的数字,我们只需要一个看到最后3位为0的自动机,我们可以只用4个状态而不是8个状态。这只是机器复杂性的一半。

事实上,这可以扩展到任何基础。对于三元基数系统,如果我们需要设计一个自动机用于9的可除性,我们只需要看看输入的最后2个数是否为0.这可以在3个状态中再次完成。

虽然如果除数不是那么特殊,那么我们只需要通过@Grijesh的回答。例如,在二元系统中,如果我们采用3或7或21的除数,我们将只需要那么多个状态。因此,对于二进制系统中的任何奇数n,我们需要n个状态来定义接受n的所有倍数的语言。另一方面,如果数字是偶数但不是2的幂(仅在二进制数的情况下),那么我们需要将数字除以2直到我们得到一个奇数,然后我们可以找到最小数量的状态添加生成的奇数和我们除以2的次数。

例如,如果我们需要找到接受所有可被20整除的二进制数的DFA的最小状态数,我们会这样做:

20/2 = 10 
10/2 = 5

因此我们的答案是5 + 1 + 1 = 7。 (1 + 1,因为我们将数字20除了两次)。

答案 1 :(得分:0)

您可以使用简单的模块化算法构建DFA。 我们可以使用以下规则将w解释为由k元数字组成的字符串

V[0] = 0
V[i] = (S[i-1] * k) + to_number(str[i])

V[|w|]w代表的数字。如果修改此规则以找到w mod N,该规则将变成此规则。

V[0] = 0
V[i] = ((S[i-1] * k) + to_number(str[i])) mod N

,每个V[i]是从0到N-1的数字之一,它对应于DFA中的每个状态。我们可以将其用作状态转换。

查看示例。

k = 2,N = 5

| V | (V*2 + 0) mod 5     | (V*2 + 1) mod 5     |
+---+---------------------+---------------------+
| 0 | (0*2 + 0) mod 5 = 0 | (0*2 + 1) mod 5 = 1 |
| 1 | (1*2 + 0) mod 5 = 2 | (1*2 + 1) mod 5 = 3 |
| 2 | (2*2 + 0) mod 5 = 4 | (2*2 + 1) mod 5 = 0 |
| 3 | (3*2 + 0) mod 5 = 1 | (3*2 + 1) mod 5 = 2 |
| 4 | (4*2 + 0) mod 5 = 3 | (4*2 + 1) mod 5 = 4 |

k = 3,N = 5

| V | 0 | 1 | 2 |
+---+---+---+---+
| 0 | 0 | 1 | 2 |
| 1 | 3 | 4 | 0 |
| 2 | 1 | 2 | 3 |
| 3 | 4 | 0 | 1 |
| 4 | 2 | 3 | 4 |

现在您可以看到一个非常简单的模式。您实际上可以构建DFA转换,只需从左到右,从上到下,从0到N-1编写重复的数字即可。