private void button7_Click(object sender, EventArgs e) { //读取NFA文件 string[] lines = File.ReadAllLines("NFA.txt"); int start = int.Parse(lines[0].Split(':')[1]); //开始符 int end = int.Parse(lines[1].Split(':')[1]); //终结符 string[] symbols = lines[2].Split(':')[1].Split(';'); //符号集 List[] nfa = new List[lines.Length - 3]; //NFA转移矩阵 for (int i = 0; i < nfa.Length; i++) { nfa[i] = new List(); } for (int i = 3; i < lines.Length; i++) { string[] parts = lines[i].Split('\t'); int from = int.Parse(parts[0]); int to = int.Parse(parts[2]); if (parts[1] == "#") //空转移 { nfa[from].Add(to); } else //普通转移 { int symbolIndex = Array.IndexOf(symbols, parts[1]); nfa[from].Add(-(symbolIndex + 1) * 1000 - to); //负数表示转移符号 } }

//NFA转DFA
List<int>[] dfa = new List<int>[1 << nfa.Length]; //DFA转移矩阵
for (int i = 0; i < dfa.Length; i++)
{
    dfa[i] = new List<int>();
}
List<int>[] dfaStates = new List<int>[dfa.Length]; //DFA状态集合
for (int i = 0; i < dfaStates.Length; i++)
{
    dfaStates[i] = new List<int>();
}
List<int> startState = new List<int>() { start }; //初始状态集合
dfaStates[0].AddRange(EpsilonClosure(startState, nfa)); //初始状态
Queue<List<int>> queue = new Queue<List<int>>();
queue.Enqueue(dfaStates[0]);
while (queue.Count > 0)
{
    List<int> currentState = queue.Dequeue();
    for (int i = 0; i < symbols.Length; i++)
    {
        List<int> nextState = new List<int>();
        foreach (int state in currentState)
        {
            foreach (int transition in nfa[state])
            {
                if (transition >= 0) //普通转移
                {
                    int symbolIndex = -1 - transition / 1000;
                    if (symbols[symbolIndex] == symbols[i])
                    {
                        nextState.Add(transition % 1000);
                    }
                }
            }
        }
        List<int> nextStateClosure = EpsilonClosure(nextState, nfa);
        if (nextStateClosure.Count > 0)
        {
            int nextStateIndex = FindStateIndex(nextStateClosure, dfaStates);
            if (nextStateIndex == -1) //新状态
            {
                nextStateIndex = AddState(nextStateClosure, dfaStates);
                queue.Enqueue(nextStateClosure);
            }
            dfa[GetStateIndex(currentState, dfaStates)].Add(i * 1000 + nextStateIndex);
        }
    }
}

//显示结果
listView2.Items.Clear();
for (int i = 0; i < dfaStates.Length; i++)
{
    string from = string.Join(",", dfaStates[i]);
    foreach (int transition in dfa[i])
    {
        int symbolIndex = transition / 1000;
        string symbol = symbols[symbolIndex];
        int to = transition % 1000;
        string toStr = string.Join(",", dfaStates[to]);
        listView2.Items.Add(new ListViewItem(new string[] { from, symbol, toStr }));
    }
}
label5.Text = string.Join(",", dfaStates[0]); //初始状态集
label7.Text = "";
for (int i = 0; i < dfaStates.Length; i++)
{
    if (dfaStates[i].Contains(end))
    {
        if (label7.Text.Length > 0)
        {
            label7.Text += ",";
        }
        label7.Text += string.Join(",", dfaStates[i]); //终止状态集
    }
}

}

//求状态集合的ε闭包 private List EpsilonClosure(List states, List[] nfa) { List closure = new List(states); Queue queue = new Queue(states); while (queue.Count > 0) { int state = queue.Dequeue(); foreach (int transition in nfa[state]) { if (transition >= 0) //普通转移 { continue; } int nextState = -transition % 1000; if (!closure.Contains(nextState)) { closure.Add(nextState); queue.Enqueue(nextState); } } } return closure; }

//查找状态集合在DFA状态集合中的索引,不存在返回-1 private int FindStateIndex(List state, List[] dfaStates) { for (int i = 0; i < dfaStates.Length; i++) { if (dfaStates[i].Count == state.Count && dfaStates[i].All(state.Contains)) { return i; } } return -1; }

//添加状态集合到DFA状态集合中,返回新状态的索引 private int AddState(List state, List[] dfaStates) { int index = dfaStates.Length; dfaStates = dfaStates.Concat(new List[] { state }).ToArray(); return index; }

//查找状态集合在DFA状态集合中的索引,不存在抛出异常 private int GetStateIndex(List state, List[] dfaStates) { int index = FindStateIndex(state, dfaStates); if (index == -1) { throw new Exception("State not found in DFA"); } return index;

不要定义或调用其他函数或类或数据结构通过VS使用C#语言实现在函数private void button3_Clickobject sender EventArgs e实现读入NFA文件功能该函数可以把选中的NFA文件的数据显示到容器listView1中该容器被分为3列初始状态、接受符号、到达状态。的基础上实现函数private void button7_Clickobject sender Ev

原文地址: https://www.cveoy.top/t/topic/ciL6 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录