Java , NFA转DFA

文章目录


可以从文件中读取NFA, 也可以在命令行中自己输入NFA的各个值。代码是算法部分。
请读者以学习为主,尽量不要直接复制粘贴运行,因为有些地方不改一下是运行不了的。
全部代码都是自己一点点打的,转载请注明出处,谢谢支持!


import java.awt.List;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map.Entry;
import java.util.Scanner;
import java.util.SortedMap;
import java.util.SortedSet;
import java.util.TreeSet;

public class nfatodfa {
    private static String chushizhuangtai = null;
    public static ArrayList zifuji = new ArrayList<>(); // 字符集
    private static ArrayList nfazhuangtai = new ArrayList<>(); // NFA状态集
    public static ArrayList jieshuzhuangtai = new ArrayList<>(); // 结束状态集
    private static ArrayList zifuhu = new ArrayList<>(); // 字符弧
    private static ArrayList konghu = new ArrayList<>(); // 空弧
    private static HashMap kongji = new HashMap<>();
    public static HashMap dfahanshu = new HashMap<>();
    private static String dfachutai = null; // DFA初始状态
    public static ArrayList a4 = new ArrayList<>(); //保存dfa每个状态

    //这个可以自行修改,本来还有个图形化界面,不过还不成熟,
    //就没有放上来
    public nfatodfa(String chushizhuangtai2,
            ArrayList jieshuzhuangtai1, ArrayList zifuji1,
            ArrayList nfazhuangtai1, ArrayList konghu2,
            ArrayList zifuhu2) {
        // TODO Auto-generated constructor stub
        this.chushizhuangtai=chushizhuangtai2;
        this.jieshuzhuangtai=jieshuzhuangtai1;
        this.zifuji=zifuji1;
        this.nfazhuangtai=nfazhuangtai1;
        this.konghu=konghu2;
        this.zifuhu=zifuhu2;
    }

    // 从开始状态开始获取下一个DFA函数状态,并保存下来
    // s5  初始状态
    public static void xhdfahanshu(String s5) {
        ArrayList aaaaaa = new ArrayList<>();
        String s6 = "";
        a4.add(s5);
        int i = 0;
        while (i != a4.size()) {
            int m = a4.size();
            String[] si = (String[]) a4.toArray(new String[m]);
            for (String zifu : zifuji) {   //遍历每一个字符
                String s1 = getzifu(si[i], zifu);
                for (int j = 0; j < s1.length(); j++) {
                    char c2 = s1.charAt(j);
                    String s2 = String.valueOf(c2);
                    String s3 = kongji.get(s2);
                    aaaaaa.add(s3);
                }
                if (!aaaaaa.isEmpty()) {
                    String s4 = strxiangjia(aaaaaa);
                    aaaaaa.clear();
                    if (!a4.contains(s4)) {
                        a4.add(s4);
                    }
                    s6 = si[i].toString();
                    s6 += ":" + zifu;
                    dfahanshu.put(s6, s4);
                }

            }
            i++;
        }
    }

     // 把N个集合进行合并
     //  每一个value都是一个集合
    // 合并后的集合
    public static String strxiangjia(ArrayList arr) {
        SortedSet sd = new TreeSet<>();
        String ss = "";
        for (String s : arr) {
            for (int i = 0; i < s.length(); i++) {
                sd.add(s.charAt(i));
            }
        }
        for (char c : sd) {
            ss += c;
        }
        return ss;
    }

    //准备工作
    // 获取S中每一个状态经过zifu生达到的状态
    public static String getzifu(String s, String zifu) {
        int i = s.length();
        String s1 = "";

        for (int j = 0; j < i; j++) {
            char c = s.charAt(j);
            String ss = String.valueOf(c);
            for (String sss : zifuhu) {
                if (sss.startsWith(ss) && sss.charAt(1) == zifu.charAt(0)) {
                    s1 += sss.charAt(2);
                }
            }
        }
        return s1;

    }

    //NFA中的每一个状态经过空弧后到达的状态
    public static void KongJi() {

        for (String s : nfazhuangtai) {
            String sss = "";
            tranji.add(s);
            Get_ztj(s);
            for (String ss : tranji)
                sss += ss;
            kongji.put(s, sss); // 某一字符经过空弧到达的状态集
            tranji.clear();

        }
    }

    // 对每一个状态遍历空弧找到等状态 在110行中使用
    private static SortedSet tranji = new TreeSet<>();   
    public static void Get_ztj(String zt) {
        for (String s : konghu) {
            if (s.startsWith(zt)) {
                tranji.add(s.substring(2));
                Get_ztj(s.substring(2));
            }
        }
    }

    public static void Get_DfaFirst(String cszt) {
        for (String s : konghu) {
            if (s.startsWith(cszt)) {
                dfachutai += s.substring(2);
                Get_DfaFirst(s.substring(2));
            }
        }
    }

    public static void GetDfaFirst() {
        dfachutai = chushizhuangtai;
        Get_DfaFirst(chushizhuangtai);
    }

    public static void wjGet_Nfa(){
        File file = new File("E:/ceshi.txt");
        String s =null;
        try {
            BufferedReader br = new BufferedReader(new FileReader(file));
            while((s=br.readLine())!=null){
                char c = s.charAt(0);
                switch (c) {
                case '0':
                    chushizhuangtai=s.substring(1);
                    break;
                case '1':
                    jieshuzhuangtai.add(s.substring(1));
                    break;
                case '2':
                    zifuji.add(s.substring(1));
                    break;
                case '3':
                    nfazhuangtai.add(s.substring(1));
                    break;
                case '4':
                    if(s.charAt(2)=='#')
                        konghu.add(s.substring(1));
                    else
                        zifuhu.add(s.substring(1));
                    break;
                default:
                    break;
                }
            }
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    public static void Get_Nfa() {
        System.out.print("输入初始状态:");
        Scanner s = new Scanner(System.in);
        chushizhuangtai = s.next(); // 初始状态
        System.out.println("输入结束状态:");
        Scanner sc5 = new Scanner(System.in);
        while (true) {
            String jieshu = sc5.next();
            if (jieshu.equals("over"))
                break;
            else {
                jieshuzhuangtai.add(jieshu);
            }
        }
        System.out.println("输入字符集:"); // 字符集
        Scanner s1 = new Scanner(System.in);
        while (true) {
            String ss1 = s1.next();
            if (ss1.equals("over")) {
                break;
            } else {
                zifuji.add(ss1);
            }
        }

        System.out.println("输入NFA状态集:");
        Scanner s2 = new Scanner(System.in);
        while (true) {
            String ss2 = s2.next();
            if (ss2.equals("over")) {
                break;
            } else {
                nfazhuangtai.add(ss2);
            }
        }

        System.out.println("输入函数集:"); // 函数集
        Scanner sc = new Scanner(System.in);
        while (true) {
            String nfa = sc.next();
            if (nfa.equals("over"))
                break;
            else if (nfa.charAt(1) == '#')
                konghu.add(nfa);
            else
                zifuhu.add(nfa);
        }

    }
//这个本来是主函数,读者可自己修改
    public static void zhixing() {
        wjGet_Nfa();
        GetDfaFirst();
        KongJi();
        xhdfahanshu(dfachutai);
        // new Tuxing(dfahanshu,a4);
        System.out.println(konghu);
        System.out.println(zifuhu);
        System.out.println(dfachutai);
        System.out.println(kongji);
        System.out.println(dfahanshu);

    }
}

你可能感兴趣的:(编译原理)