关于形式语言与自动机的文法一个小小的思考

2023-12-10 19:40

本文主要是介绍关于形式语言与自动机的文法一个小小的思考,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

基础回顾
  • 根据Chomsky文法体系划分为四类,0,1,2,3型。
  • 由文法G产生的语言记为L(G)
  • L(G)中的一个字符串,必是由终结符组成的,并且是从起始符S推导出来的
  • 0型文法:无限制文法
  • 1型文法,也称上下文有关文法。在这里插入图片描述
  • 2型文法,也称上下文无关文法。在这里插入图片描述
  • 3型文法,也称正则文法。在这里插入图片描述
  • 不含A→ε的2型、3型属于1型,1型、2型、3型均属于0型。
  • 1型 ,不允许A→ε形式。

思考

那么如何利用这四种类型设置好简单语言的文法是值得考虑的事情。

首先一个例题看看:
在这里插入图片描述
分析: 首先明白证明两个集合相等是需要双向证明的。L是上述生成式生成的语言的集合,而等号右边是一般形式的生成句子的集合。

  1. 切入点有两个S->aSBC;S->aBC;要获得右边n个字符的连接,很明显带入n次即可。
  2. 可以分别尝试两个,如S->aBC;进行自身的代入整合可得S->an(BC)n
  3. 获得a的n次方了,可能是正确的做法。我们后面就考虑(BC)n的处理问题。
  4. an(BC)n,在提供的生成式中肯定会先找aB->ab,因为只有这一个才能带入使用,其他都不能。
  5. 进行一下处理,得到an-1aB(BC)n-1C,代入可得anb(BC)n-1C,那么很明显,我们获得了b,那么刚好式子bB->bb发挥作用,依次拆解得到anbnCn
  6. 那么C的处理一样,带入bC->bc,再代入cC->cc即可得到anbncn,即证L包含于L(G)。

同理,再证L(G)->L的关系。
从S开始只能用①和②得到含a,B,C的字符串,且字符串中这3个字母的个数相同。而b和c分别只能用B和C换取,因此L(G)的字符串中a,b,c的个数相同。又a始终出现在其他符号的左边,B只有紧挨在a或b的右边时才能被替换成b,C只有紧挨在b或c的右边时才能被替换成c,因此b必在a的右边,又必在b的右边,得证L(G)->CL。

  1. 构造右线性文法,识别语言L={a3n+1|n >=0}。那么在这里插入图片描述这是基本定义,但是要是3的倍数并且余1,说明每次都增加三个字符,要么是开始时只有一个,要么到最后结束时增加一个即可,全程都是每次增加三个字符,所以就是S->aaaS|a或者
    在这里插入图片描述
  2. 构造上下文无关文法,能够产生L= {wl​​​​​​​​​​​​​​ w属于{a,b}*且w中a的个数是b的两倍}。
    那么构造a的数目是b的两倍,说明每次增加的时候都是至少按照你加2我加1的形式增加,
    那么简单一个式子就是S->aabS,S->aab,这样子就差不多了,但是要考虑所有的组合情况,那么排列顺序是一个值得考虑的问题,S->aab,S->aba,S->baa都是存在的排列方式,所以在这三者中的任意位置插入新增位置都是可以的
    S->aSab|aaSb|aabS|Saab,
    S->Saba|aSba|abSa|abaS,
    S->Sbaa|bSaa|baSa|baaS,
    这样子写有点繁琐,那么我们可以采用动态规划的思想,就是增加
    在这里插入图片描述
    那么我们借助这个,进行动态拆分,即S->SaSaSbS|SaSbSaS|SbSaSaS就可满足上述要求。
  3. 还比如写一个以1开始以01结尾的串的生成式
    那么确定以1开始,得到S->1A,然后1的后面可以跟0或者1,即A->0A|1A|0,并且也完成了以1结束的目的,所以,做这些题的时候学会一步一步根据特点拆解很重要。可能有的解不唯一。

最后举一个作业里面的典型习题
找出右线性文法,能构成具有奇数个a和奇数个b组成的字符串。
分析: 当时做这个题的时候,我们会思考如何保证一定是奇数个呢?按照常规思路来说,在1个的基础上每次增加的时候都增加两个或者进行两次增加同一类型元素的操作,那么就一定能保证结果是奇数个。
那么先确定最开始的字符要么是a要么是b,那么
在这里插入图片描述
所以综合来看的结果是
在这里插入图片描述
示意图
在这里插入图片描述

这篇关于关于形式语言与自动机的文法一个小小的思考的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/478152

相关文章

hdu 3065 AC自动机 匹配串编号以及出现次数

题意: 仍旧是天朝语题。 Input 第一行,一个整数N(1<=N<=1000),表示病毒特征码的个数。 接下来N行,每行表示一个病毒特征码,特征码字符串长度在1—50之间,并且只包含“英文大写字符”。任意两个病毒特征码,不会完全相同。 在这之后一行,表示“万恶之源”网站源码,源码字符串长度在2000000之内。字符串中字符都是ASCII码可见字符(不包括回车)。

POJ 1625 自动机

给出包含n个可见字符的字符集,以下所提字符串均由该字符集中的字符构成。给出p个长度不超过10的字符串,求长为m且不包含上述p个字符串的字符串有多少个。 g++提交 int mat[108][108] ;int matn ;int N ;map<char ,int> to ;//ACconst int maxm = 108 ;const int kin

zoj 3228 ac自动机

给出一个字符串和若干个单词,问这些单词在字符串里面出现了多少次。单词前面为0表示这个单词可重叠出现,1为不可重叠出现。 Sample Input ab 2 0 ab 1 ab abababac 2 0 aba 1 aba abcdefghijklmnopqrstuvwxyz 3 0 abc 1 def 1 jmn Sample Output Case 1 1 1 Case 2

【编程底层思考】垃圾收集机制,GC算法,垃圾收集器类型概述

Java的垃圾收集(Garbage Collection,GC)机制是Java语言的一大特色,它负责自动管理内存的回收,释放不再使用的对象所占用的内存。以下是对Java垃圾收集机制的详细介绍: 一、垃圾收集机制概述: 对象存活判断:垃圾收集器定期检查堆内存中的对象,判断哪些对象是“垃圾”,即不再被任何引用链直接或间接引用的对象。内存回收:将判断为垃圾的对象占用的内存进行回收,以便重新使用。

【编程底层思考】详解Java的JUC多线程并发编程底层组件AQS的作用及原理

Java中的AbstractQueuedSynchronizer(简称AQS)是位于java.util.concurrent.locks包中的一个核心组件,用于构建锁和其他同步器。AQS为实现依赖于FIFO(先进先出)等待队列的阻塞锁和相关同步器提供了一套高效、可扩展的框架。 一、AQS的作用 统一同步状态管理:AQS提供了一个int类型的成员变量state,用于表示同步状态。子类可以根据自己

通过C语言将文法转化为语言

最近在学习编译原理,在做一道题时,突然产生想法,想通过C语言将文法产生的语言表现出来。   题目如下:   给定文法:S::=aB|bA                     A::=aS|bAA|a                     B::=bS|aBB|b   该文法所产生的语言是什么?   程序如下,可以注意相关的程序注解 #include<stdio.h> #in

正规式与有限自动机例题

答案:D 知识点: 正规式 正规集 举例 ab 字符串ab构成的集合 {ab} a|b 字符串a,b构成的集合 {a,b} a^* 由0或者多个a构成的字符串集合 {空,a,aa,aaa,aaaa····} (a|b)^* 所有字符a和b构成的串的集合 {空,a,b,ab,aab,aba,aaab····} a(a|b)^* 以a为首字符的a,b字符串的集

一道算法题引发的动态内存管理的思考

在做PKU2762时,需要建邻接表。 于是按部就班写了下面一个插入边到邻接表中的函数: const int VMAX = 1010;typedef struct Graph{int vex;Graph* next;}Graph;Graph ArcGraph[VMAX];void insert(int u, int v){Graph* t = new Graph;Graph*

go 和 java 技术选型思考

背景:       go和java我这边自身都在使用,感受比较深,java使用了有7年多,go也就是今年开始的,公司需要所以就学了使用,发现这两个语言都很好,需要根据场景选择,我写下我这边的看法。 关于go和java语言层面和特性就不说了,网上都有,我这边从我这边实际使用的场景情况来说,供大家参考。 给我最大的感受,php转go的不少,也是符合未来技术大趋势的,目前来看,java转go也比较