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. QList, QLinkedList, QVector, QStack, QQueue的区别,以前也没见过QCache,而且可以自定义cost

    http://doc.qt.io/qt-4.8/containers.html http://doc.qt.io/qt-4.8/qcache.html

  2. win32界面程序开发,自制一个会自动销毁的提示框

    思路:创建线程里面启动窗口,设置定时器关闭该窗口. 创建窗口几个步骤和一般窗口无异,注册.然后createwindow,之后showwinodw,然后消息循环. 在createwindow之后,获取到 ...

  3. 【原创】基于Docker的CaaS容器云平台架构设计及市场分析

    基于Docker的CaaS容器云平台架构设计及市场分析 ---转载请注明出处,多谢!--- 1 项目背景---概述: “在移动互联网时代,企业需要寻找新的软件交付流程和IT架构,从而实现架构平台化,交 ...

  4. Qt自定义委托在QTableView中绘制控件、图片、文字(内容比较全)

    自定义委托,继承于,QStyledItemDelegate类,重载Paint()函数, 1.实现在QTableView中绘制 格式字符串 2.实现在QTableView中绘制进度条 3.实现在QTab ...

  5. Delphi url 编码及转码及特殊字符串替换--百度和腾讯用的就是这个

    先介绍一下,Delphi中处理Google的URL编码解码,其中就会明白URL编码转换的方法的 从delphi的角度看Google(谷歌)URL编码解码方式 在网上搜索了一下,似乎没有什么关于goog ...

  6. 获取其他进程中“Internet Explorer_TridentCmboBx”的内容

    function GetTridentCmboBxText( // 获取其他进程中“Internet Explorer_TridentCmboBx”的内容   mHandle: THandle; // ...

  7. getch(),getche(),getchar()的区别

    先说基本区别. (1) getch()和getche()函数     这两个函数都是从键盘上读入一个字符.其调用格式为:      getch();      getche();     两者的区别是 ...

  8. 一键增加swap空间脚本

    #!/bin/bash echo -e "\033[33m Your current swap is \033[0m" free -h mkdir /SwapDir cd /Swa ...

  9. c#编写的基于Socket的异步通信系统封装DLL--SanNiuSignal.DLL

    SanNiuSignal是一个基于异步socket的完全免费DLL:它里面封装了Client,Server以及UDP:有了这个DLL:用户不用去关心心跳:粘包 :组包:发送文件等繁琐的事情:大家只要简 ...

  10. git初学【常用命令、上传项目到码云或从码云拉取、克隆项目】

    1.下载git.https://git-scm.com/   注册码云:https://gitee.com/2.安装git:  默认安装即可:  安装完成之后打开git bash进行最后一步配置  输 ...