一般来说,在查看一种语言时,判断该语言是否规则的一个很好的经验法则是考虑一个可以读取字符串并回答问题“这个字符串在语言中吗?”的程序
要编写这样的程序,您是否需要在变量中存储一些任意值,或者程序的状态(即所有可能变量值的组合)是否仅限于有限的固定数量的可能性?如果该语言可以被只需要固定数量的变量且只能具有固定数量的值的程序识别,那么您就有了常规语言。如果不是,那就不是。
使用这个,我可以看到第一种语言不是正则的,但第二种语言是。在第一语言中,我需要记住我见过多少as,以及多少bs。 (或者至少,我需要跟踪 (# of as) - (# of bs),并在该计数为负时接受字符串是否结束)。同时,as 的数量没有限制,所以这个数量可以任意大。
在第二种语言中,我根本不在乎 n 和 m 是什么。所以对于第二种语言,我的程序只会跟踪“我至少见过一个b 了吗?”确保在第一个 b 之后没有出现任何 a 字符。 (所以,一个变量只有两个值 - true 或 false)
因此,将语言 1 变为常规语言的一种方法是将其更改为:
1. L={w ∈ {a,b}*/no of a in (w) < no of b in (w), and no of a in (w) < 100}
现在我不需要跟踪我在达到 100 后看到的 as 的数量(从那时起我自动知道该字符串不在该语言中),同样使用bs 的数量 - 一旦达到 100,我就可以停止计数,因为我知道这已经足够了,除非 as 的数量本身太大。
您应该注意的一个常见情况是,当有人询问您有关“as 的数量是 13 的倍数”或“w ∈ {0,1} * 和 w 是 13" 的倍数的二进制表示。有了这些,您似乎需要跟踪整个数字来做出决定,但实际上您不需要 - 在这两种情况下,您只需要保留一个可以从 0 计数到 12 的变量。所以请注意用于“多种”类型的语言。 (以及相关的“奇数”或“偶数”或“比13的倍数多1”)
虽然其他数学属性 - 例如,w ∈ {0,1}* 和 w 是完美正方形的二进制表示 - 将导致非常规语言。