确定有穷自动机

确定有穷自动机

思路:

将状态与对应的行,符号与对应的列 索引进行映射,输入规则为状态转换表,之后输入待判断的字符串,判断是否会被自动机接受


package com.parting_soul;

import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;

/**
 * 确定有穷自动机
 * 将状态与对应的行,符号与对应的列 索引进行映射
 * @author parting_soul
 *
 */
public class Dfa {
	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		DfaStorage s = new DfaStorage();
		s.inputDFA();
		s.print();
		String str = null;
		while (!(str = in.nextLine()).equals("-1")) {
			System.out.println(s.judge(str));
		}
	}
}

class DfaStorage {
	int[][] maxtra = new int[100][];
	int kNum, eNum;
	Map<String, Integer> K = new HashMap<>();
	Map<String, Integer> E = new HashMap<>();
	Map<String, Integer> exit = new HashMap<>();
	int currentState = 0;

	/**
	 * 判断句子是否被DFA所接受
	 * 
	 * @param str
	 * @return
	 */
	public boolean judge(String str) {
		for (int i = 0; i < str.length(); i++) {
			String c = String.valueOf(str.charAt(i));
			int nextState = -1;
			Integer inter = E.get(c);
			if (inter != null) {
				nextState = maxtra[currentState][inter];
			}
			if (nextState == -1 || inter == null) {
				return false;
			}
			currentState = nextState;
		}
		System.out.println(currentState);
		if (exit.get(getState(currentState)) == 1) {
			return true;
		}
		return false;
	}

	/**
	 * 取得当前的状态(终结,非终结)
	 * 
	 * @param value
	 * @return
	 */
	public String getState(int value) {
		for (Map.Entry<String, Integer> entry : K.entrySet()) {
			if (entry.getValue().equals(value)) {
				return entry.getKey();
			}
		}
		return null;
	}

	public DfaStorage() {
		// TODO Auto-generated constructor stub
	}

	/**
	 * 输入状态转换表
	 */
	public void inputDFA() {
		Scanner in = new Scanner(System.in);
		System.out.println("输入自动机状态个数和自动机符号个数");
		kNum = in.nextInt();
		eNum = in.nextInt();
		System.out.println("输入自动机状态:(第一个默认为开始符) 第二个输入为是否是结束符");
		for (int i = 0; i < kNum; i++) {
			String k = in.next();
			K.put(k, i);
			int isExit = in.nextInt();
			exit.put(k, isExit);
		}
		System.out.println("输入自动机符号");
		for (int i = 0; i < eNum; i++) {
			String e = in.next();
			E.put(e, i);
		}
		init();
		System.out.println("输入状态函数转换表");
		for (int i = 0; i < kNum; i++) {
			for (int j = 0; j < maxtra[i].length; j++) {
				maxtra[i][j] = K.get(in.next());
			}
		}
	}

	/**
	 * 初始化maxtra初始状态为不可达
	 */
	private void init() {
		for (int i = 0; i < kNum; i++) {
			maxtra[i] = new int[eNum];
			for (int j = 0; j < maxtra[i].length; j++) {
				maxtra[i][j] = -1;
			}
		}
	}

	public void print() {
		for (int i = 0; i < kNum; i++) {
			for (int j = 0; j < eNum; j++) {
				System.out.print(maxtra[i][j] + " ");
			}
			System.out.println();
		}

		for (Map.Entry<String, Integer> entry : exit.entrySet()) {
			System.out.println(entry.getKey() + " " + entry.getValue());
		}
	}
}



1. 实验内容 每一个正规集都可以由一个状态数最少的DFA所识别,这个DFA是唯一的(不考虑同构的情况)。任意给定的一个DFA,根据以下算法设计一个C程序,将该DFA 化简为与之等价的最简DFA。 2. 实验设计分析 2.1 实验设计思路 根据实验指导书和书本上的相关知识,实现算法。 2.2 实验算法 (1)构造具有两个组的状态集合的初始划分I:接受状态组 F 和非接受状态组 Non-F。 (2)对I采用下面所述的过程来构造新的划分I-new. For I 中每个组G do Begin 当且仅当对任意输入符号a,状态s和读入a后转换到I的同一组中; /*最坏情况下,一个状态就可能成为一个组*/ 用所有新形成的小组集代替I-new中的G; end (3)如果I-new=I,令I-final=I,再执行第(4)步,否则令I=I=new,重复步骤(2)。 (4)在划分I-final的每个状态组中选一个状态作为该组的代表。这些代表构成了化简后的DFA M'状态。令s是一个代表状态,而且假设:在DFA M中,输入为a时有从s到t转换。令t所在组的代表是r,那么在M’中有一个从s到r的转换,标记为a。令包含s0的状态组的代表是M’的开始状态,并令M’的接受状态是那些属于F的状态所在组的代表。注意,I-final的每个组或者仅含F中的状态,或者不含F中的状态。 (5)如果M’含有死状态(即一个对所有输入符号都有刀自身的转换的非接受状态d),则从M’中去掉它;删除从开始状态不可到达的状态;取消从任何其他状态到死状态的转换。 。。。。。。
1. 实验内容 每一个正规集都可以由一个状态数最少的DFA所识别,这个DFA是唯一的(不考虑同构的情况)。任意给定的一个DFA,根据以下算法设计一个C程序,将该DFA 化简为与之等价的最简DFA。 2. 实验设计分析 2.1 实验设计思路 根据实验指导书和书本上的相关知识,实现算法。 2.2 实验算法 (1)构造具有两个组的状态集合的初始划分I:接受状态组 F 和非接受状态组 Non-F。 (2)对I采用下面所述的过程来构造新的划分I-new. For I 中每个组G do Begin 当且仅当对任意输入符号a,状态s和读入a后转换到I的同一组中; /*最坏情况下,一个状态就可能成为一个组*/ 用所有新形成的小组集代替I-new中的G; end (3)如果I-new=I,令I-final=I,再执行第(4)步,否则令I=I=new,重复步骤(2)。 (4)在划分I-final的每个状态组中选一个状态作为该组的代表。这些代表构成了化简后的DFA M'状态。令s是一个代表状态,而且假设:在DFA M中,输入为a时有从s到t转换。令t所在组的代表是r,那么在M’中有一个从s到r的转换,标记为a。令包含s0的状态组的代表是M’的开始状态,并令M’的接受状态是那些属于F的状态所在组的代表。注意,I-final的每个组或者仅含F中的状态,或者不含F中的状态。 (5)如果M’含有死状态(即一个对所有输入符号都有刀自身的转换的非接受状态d),则从M’中去掉它;删除从开始状态不可到达的状态;取消从任何其他状态到死状态的转换。 。。。。。。
### 确定有穷自动机(DFA)的定义 确定有穷自动机(Deterministic Finite Automaton,简称 DFA)是一种用于识别正则语言的抽象模型。它由五个部分组成:一组状态 \( Q \),一个输入字母表 \( \Sigma \),一个转移函数 \( \delta : Q \times \Sigma \to Q \),一个初始状态 \( q_0 \in Q \),以及一组接受状态 \( F \subseteq Q \)[^1]。 具体来说: - **状态集合 \( Q \)** 是有限的一组状态。 - **输入字母表 \( \Sigma \)** 是字符的有限集合,表示可能的输入符号。 - **转移函数 \( \delta \)** 描述了当前状态下读取特定输入符号后如何转移到另一个状态。 - **初始状态 \( q_0 \)** 表示处理输入字符串前的起始位置。 - **接受状态集合 \( F \)** 中的状态表明哪些情况下输入被认为是有效的。 ### 工作原理 当一个 DFA 接收一个输入字符串时,其操作过程如下: - 开始于初始状态 \( q_0 \)。 - 对于输入字符串中的每个字符,按照转移函数逐步移动到下一个状态[^2]。 - 如果在读完整个字符串之后处于任意一个接受状态,则该字符串被认定为属于此 DFA 所描述的语言;反之,如果不位于任何接受状态,则认为该字符串不属于所描述的语言。 例如,在实际应用中,可以构建这样的 DFA 来匹配某些模式或者验证语法结构是否正确。下面是一个简单的例子展示如何编写一个基本的 DFA: ```python def dfa_accepts(dfa, input_string): current_state = dfa['initial'] for symbol in input_string: if (current_state, symbol) not in dfa['transition']: return 'not accept' current_state = dfa['transition'][(current_state, symbol)] return 'accept' if current_state in dfa['final'] else 'not accept' # Example DFA definition dfa_example = { 'states': {'q0', 'q1', 'q2'}, 'alphabet': {'a', 'b'}, 'transition': {('q0','a'):'q1', ('q1','b'):'q2'}, 'initial': 'q0', 'final': {'q2'} } print(dfa_accepts(dfa_example, "ab")) # Output: accept ``` 在这个 Python 示例中展示了基于字典形式定义的一个简单 DFA 及其实现逻辑来检测指定字符串是否符合条件。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值