DFA(确定的有穷自动机)

一个确定的有穷自动机M是一个五元组:

M=(K,∑,f,S,Z)
  1. K是一个有穷集,它的每个元素称为一个状态。
  2. ∑是一个有穷字母表,它的每一个元素称为一个输入符号,所以也陈∑为输入符号表。
  3. f是转换函数,是Kx∑->K上的映象。
  4. S∈K,是唯一的一个初态。
  5. Z∈K,是一个终态集,终态也称可接受状态或结束状态。

实例代码

  1. 实现文法
G[S]:
S->aU|bV
U->bV|aQ
Q->aQ|bQ
  1. 状态图

  2. 代码实现

 -*- coding: utf-8 -*- #
#@author: chlinlearn
#@createTime: 2019/4/13 14:12
#@fileName: DFA
class DFA():
def __init__(self):
#状态集
self.listEdge = []
#初态
self.S = []
#终态
self.Z = [] #判断是否是终态集
def isZ(self,ch):
for i in range(0,len(self.Z)) :
if self.Z[0] == ch or self.Z[1] == ch:
return True
else:
return False #输入
def input(self):
self.S = input("请输入开始符:")
self.Z = input("请输入终态集(终集符组成的一个字符串):")
self.Z = self.Z.split(",")
print("请输入正规文法以exit结尾:")
print("example:S,aZ")
while(True):
list = []
inStr = input()
if inStr=='exit':
break
inStr = inStr.split(',')
# 读取第一个状态集
s = inStr[0]
for i in range(0,len(inStr[1])):
#ch,ns
if len(inStr[1])==2:
c = inStr[1][0]
n = inStr[1][1]
list = [s,c,n]
self.listEdge.append(list)
elif len(inStr[1])==1:
c = inStr[1][0]
list = [s, c, self.Z[0]]
self.listEdge.append(list) #转换函数
def isNextState(self,s,ch):
for i in range(0,len(self.listEdge)):
if s == self.listEdge[i][0] and ch == self.listEdge[i][1]:
return self.listEdge[i][2]
return def judgeDFA(self):
print("请输入要判断的字符串:")
while(True):
#获取字母表
str = input()
if '#' in str :
print("程序已退出,欢迎下次使用!")
return
temp = self.S[0]
for i in range(0,len(str)):
if str[i] is 'a':
temp = self.isNextState(temp,'a')
elif str[i] is 'b':
temp = self.isNextState(temp, 'b')
else:
break
if self.isZ(temp):
print("此字符串“属于”该文法!")
else:
print("此字符串“不属于”该文法!")
print("再次判断请输入字符串(退出程序输入#):") if __name__ == '__main__':
DFA = DFA()
DFA.input()
DFA.judgeDFA()

总结

这是我在课程中的一个实验,代码手写并且可运行,是参照一个java版的代码实现的,加上自己的理解和思路把它以python的形式实现。学习别人好的地方,当然也不能照搬别人,不然能够为己用的东西少之又少。通过不同的编程语言把整个思路在理一遍能够加深自己的理解,并且能够得到一样的运行结果,说明自己的理解是对的。最后也附上对应的java版代码,有需求的童鞋可以参考喔!

欢迎访问我的个人网站www.chlinlearn.cn

附件

java版DFA

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner; class edge { char PriorityState;
char ch;
char NextState;
edge(char p,char c, char n){
PriorityState = p;
ch = c;
NextState = n;
}
@Override
public String toString() {
return "edge [PriorityState=" + PriorityState + ", ch=" + ch + ", NextState=" + NextState + "]";
}
}
/**DFA的构造*/
public class DFA {
static List<edge> listEdge = new ArrayList<edge>();//状态集
//static HashMap<edge, Character> mapEdge = new HashMap<>();
static String S;//初态集
static String Z;//终态集
//flag is here
static boolean judeZ(char ch){
for(int j=0; j<Z.length(); j++){
if(Z.charAt(j)==ch) return true;
}
return false;
}
static void input() {
Scanner in = new Scanner(System.in);
String instr = null;
String subStr[] = null;
System.out.println("请输入开始符:");
S = in.next();
System.out.println("请输入终态集(终集符组成的一个字符串):");
Z = in.next();
System.out.println("请输入正规文法以end结尾(形式如下图):");
System.out.println("----------");
System.out.println("| S-aU |");
System.out.println("| S-bV |");
System.out.println("| U-bV |");
System.out.println("| .... |");
System.out.println("| end |");
System.out.println("----------");
while(in.hasNext()){
instr = in.next();
if("end".equals(instr))
break;
subStr = instr.split("-|\\|");//连字符
System.out.println("subStr:"+subStr);
String s = subStr[0];//读取一行f(转换函数)
System.out.println(s);
for(int i=1; i<subStr.length; i++){
edge e = null;
System.out.println(subStr[1]);
if(subStr[i].length()==2){
char c = subStr[i].charAt(0);//字母表
char n = subStr[i].charAt(1);//状态集
listEdge.add(new edge(s.charAt(0),c,n));//f(S,a)=U
} if(subStr[i].length()==1){
char c = subStr[i].charAt(0);
listEdge.add(new edge(s.charAt(0),c,Z.charAt(0)));
}
}
}
} static char judeNextState(char s,char ch){
for(int i=0; i<listEdge.size(); i++){
if(s==listEdge.get(i).PriorityState && ch==listEdge.get(i).ch){
return listEdge.get(i).NextState;
}
}
return '0';
} static void judeDFA(){
Scanner in = new Scanner(System.in);
System.out.println("请输入要判断的字符串:");
while(in.hasNext()){
String str = in.next();
if(str.equals("#")){
System.out.println("程序已退出,欢迎下次使用!");
return;
}
char temp = S.charAt(0);
int i=0;
//System.out.println(temp+" "+mapEdge.get(e));
for(; i<str.length(); i++){
//System.out.println("temp="+temp);
if(str.charAt(i)=='a'){
temp = judeNextState(temp, 'a');
}
else if(str.charAt(i)=='b'){
temp = judeNextState(temp, 'b');
}
else break;
}
//flag is here
if(i>=str.length() && judeZ(temp)) System.out.println("此字符串“属于”该文法!");
else System.out.println("此字符串“不属于”该文法!");
System.out.println("再次判断请输入字符串(退出程序输入#):");
} } /*main*/
public static void main(String[] args) {
// TODO Auto-generated method stub
DFA.input();
DFA.judeDFA();
}
}

python实现DFA模拟程序(附java实现代码)的更多相关文章

  1. 深入一致性哈希(Consistent Hashing)算法原理,并附100行代码实现

    转自:https://my.oschina.net/yaohonv/blog/1610096 本文为实现分布式任务调度系统中用到的一些关键技术点分享——Consistent Hashing算法原理和J ...

  2. python实现文章或博客的自动摘要(附java版开源项目)

    python实现文章或博客的自动摘要(附java版开源项目) 写博客的时候,都习惯给文章加入一个简介.现在可以自动完成了!TF-IDF与余弦相似性的应用(三):自动摘要 - 阮一峰的网络日志http: ...

  3. Java架构师方案—多数据源开发详解及原理(二)(附完整项目代码)

    1. mybatis下数据源开发工作 2. 数据源与DAO的关系原理模型 3. 为什么要配置SqlSessionTemplate类的bean 4. 多数据源应用测试 1. mybatis下数据源开发工 ...

  4. 简单的词法设计——DFA模拟程序

    实验一.简单的词法设计--DFA模拟程序 一.实验目的 通过实验教学,加深学生对所学的关于编译的理论知识的理解,增强学生对所学知识的综合应用能力,并通过实践达到对所学的知识进行验证.通过对 DFA 模 ...

  5. 经典KMP算法C++与Java实现代码

    前言: KMP算法是一种字符串匹配算法,由Knuth,Morris和Pratt同时发现(简称KMP算法).KMP算法的关键是利用匹配失败后的信息,尽量减少模式串与主串的匹配次数以达到快速匹配的目的.比 ...

  6. 100本Python精品书籍(附pdf电子书下载)

    51本Python精品书籍(附下载)链接: https://pan.baidu.com/s/19ydAKCFxM0plkepXMlqQLg 提取码: nnpe 400集python视频教程下载:链接: ...

  7. java混淆代码的使用

    前言:为了保护我们的劳动成果,我们来学习java混淆代码工具的使用. 1.下载retroguard.jar 进入http://www.retrologic.com/retroguard-downloa ...

  8. Python学习笔记:与Java 基础语法对比

    闲着无聊学习下Python 的语法.由于我目前主要编程语言还是Java ,所以针对Python 的学习我主要是通过与Java 进行对比.我使用的是Python3,因此语法上也会遵循Python3 的规 ...

  9. Scala IDEA for Eclipse里用maven来创建scala和java项目代码环境(图文详解)

    这篇博客 是在Scala IDEA for Eclipse里手动创建scala代码编写环境. Scala IDE for Eclipse的下载.安装和WordCount的初步使用(本地模式和集群模式) ...

随机推荐

  1. no identifier specified for entity错误

    未给entity类添加主键造成. 之前出现这个错误是因为忘记给id添加@Id标签.

  2. Android零基础入门第60节:日历视图CalendarView和定时器Chronometer

    原文:Android零基础入门第60节:日历视图CalendarView和定时器Chronometer 上一期学习了AnalogClock.DigitalClock和TextClock时钟组件,本期继 ...

  3. Delphi 10.2 非官方补丁合集

    Delphi 10.2 非官方补丁合集http://blog.qdac.cc/?p=4485 FMXObject和TFORM的释放都变成异步了.虽然能保证是在主线程中释放,但是Windows部分的线程 ...

  4. 深入了解Windows句柄到底是什么(句柄是逻辑指针,或者是指向结构体的指针,图文并茂,非常清楚)good

    总是有新入门的Windows程序员问我Windows的句柄到底是什么,我说你把它看做一种类似指针的标识就行了,但是显然这一答案不能让他们满意,然后我说去问问度娘吧,他们说不行网上的说法太多还难以理解. ...

  5. PNG透明窗体全攻略(控件不透明)

    http://blog.csdn.net/riklin/article/details/4417247 看好了,这是XP系统,未装.net.我的Photoshop学的不太好,把玻璃片弄的太透了些,如果 ...

  6. 做了一个浏览指定文件格式的 TreeView(方便查看Source目录下的源码)

    unit DirTreeView; interface uses   SysUtils, Classes, Controls, Forms, ComCtrls; type   TDirTreeView ...

  7. OpenCv的python环境搭建

    1.python的安装参看 http://www.cnblogs.com/samo/p/6734403.html 2.OpenCv安装.opencv2.4.10可以支持vc10/vc11/vc12,o ...

  8. IO多路复用与异步非阻塞

    1.基于socket,发送http请求 import socket import requests # 方式一 list=['li','gh ','nn'] for i in list: ret=re ...

  9. 深度强化学习day01初探强化学习

    深度强化学习 基本概念 强化学习 强化学习(Reinforcement Learning)是机器学习的一个重要的分支,主要用来解决连续决策的问题.强化学习可以在复杂的.不确定的环境中学习如何实现我们设 ...

  10. 使用 Gitlab CI/CD 实现自动化发布站点到 IIS

    说明 这里先介绍下两个东西 CI/CD.GitLab Runner,当然在此之前你需要对 git 有所了解,关于 git 这里不做说明,可以自行百度. 首先介绍 CI/CD :随着我们开发方式的转变, ...