📌  相关文章
📜  用于构建DFA的程序,该DFA接受以不同字符开头和结尾的字符串

📅  最后修改于: 2021-04-29 09:00:42             🧑  作者: Mango

先决条件:确定性有限自动机
给定字符串, str由字符“ a”和“ b”组成。任务是检查字符串str是否以不同的字符开头和结尾。如果是这样,则打印“ YES”并进行状态转换,否则打印“ NO”。
例子:

在DFA中,没有记忆的概念,因此我们必须通过字符来检查字符串的字符,与第0字符开始。该问题的输入字符集为{a,b} 。为了使DFA有效,必须为每个状态下的输入集的每个符号定义一个转换规则,以转换为有效状态。
DFA计算机:对于上述问题,请构建DFA计算机。它类似于具有各种状态和转换的流程图。与上述问题相对应的DFA机器如下所示,Q2和Q4是最终状态:

解释:
假设输入字符串的第一个字符为“ a”,然后在读取“ a”时,控件将移至机器的上级分支。现在,已定义该字符串不得以“ a”结尾才能被接受。在状态Q1处,如果再次出现’a’,则它将继续在相同状态下盘旋,因为对于机器而言,最后读取的字符可能是字符串的最后一个字符。如果它得到一个“ b”,则它可以进入最终状态,因为在这种情况下,以“ b”结尾的字符串是可以接受的,因此它进入状态Q2。在这里,如果它得到一个“ a”,它将再次进入非最终状态,否则对于连续的“ b”,它将继续在最终状态中盘旋。
当第一个字符被检测为“ b”时,情况相同。
方法:

  1. 定义制作状态图所需的最小状态数。将功能使用到各种状态。
  2. 列出所有有效的过渡。每个状态必须对每个有效符号都有一个过渡。
  3. 通过应用基本条件定义最终状态。
  4. 使用状态函数调用定义所有状态转换。
  5. 为字符串的末尾定义一个返回条件。

对于给定的DFA机器,规格如下:

  1. Q0,Q1,Q2,Q3,Q4是已定义的状态。
  2. a和b是有效符号。每个状态都有一个为a和b定义的过渡。
  3. Q2和Q4被定义为最终状态。如果字符串输入在这些状态中的任何一个处结束,则将其接受,否则将被拒绝。
  4. 假设在状态Q0,如果出现“ a”,则对Q1进行函数调用。如果出现“ b”,则对Q3进行函数调用。
  5. 如果通过执行该过程,程序到达字符串的末尾,则根据程序所处的状态进行输出。

下面是上述方法的实现:

C++
// CPP Program to DFA that accepts
// string if it starts and end with
// same character
#include 
using namespace std;
 
// various states of DFA machine
// are defined using functions.
bool q1(string, int);
bool q2(string, int);
bool q3(string, int);
bool q4(string, int);
 
// vector to store state transition
vector state_transition;
 
// end position is checked using string
// length value.
// q0 is the starting state.
// q2 and q4 are intermediate states.
// q1 and q3 are final states.
 
bool q1(string s, int i)
{
    state_transition.push_back("q1");
    if (i == s.length()) {
        return false;
    }
 
    // state transitions
    // a takes to q1, b takes to q2
    if (s[i] == 'a')
        return q1(s, i + 1);
    else
        return q2(s, i + 1);
}
 
bool q2(string s, int i)
{
    state_transition.push_back("q2");
    if (i == s.length()) {
        return true;
    }
 
    // state transitions
    // a takes to q1, b takes to q2
    if (s[i] == 'a')
        return q1(s, i + 1);
    else
        return q2(s, i + 1);
}
 
bool q3(string s, int i)
{
    state_transition.push_back("q3");
    if (i == s.length()) {
        return false;
    }
 
    // state transitions
    // a takes to q4, 1 takes to q3
    if (s[i] == 'a')
        return q4(s, i + 1);
    else
        return q3(s, i + 1);
}
 
bool q4(string s, int i)
{
    state_transition.push_back("q4");
    if (i == s.length()) {
        return true;
    }
 
    // state transitions
    // a takes to q4, b takes to q3
    if (s[i] == 'a')
        return q4(s, i + 1);
    else
        return q3(s, i + 1);
}
 
bool q0(string s, int i)
{
    state_transition.push_back("q0");
    if (i == s.length()) {
        return false;
    }
 
    // state transitions
    // a takes to q1, b takes to q3
    if (s[i] == 'a')
        return q1(s, i + 1);
    else
        return q3(s, i + 1);
}
 
int main()
{
    string s = "ababab";
 
    // all state transitions are printed.
    // if string is acceptable, print YES.
    // else NO is printed
    bool ans = q0(s, 0);
    if (ans) {
        cout << "YES" << endl;
 
        // print transition state of given
        // string str
        for (auto& it : state_transition) {
            cout << it << ' ';
        }
    }
    else
        cout << "NO" << endl;
    return 0;
}


Java
// Java Program to DFA that accepts
// string if it starts and end with
// same character
import java.util.*;
 
class GFG
{
     
    // vector to store state transition
    static Vector state_transition = new Vector();
     
    // end position is checked using string
    // length value.
    // q0 is the starting state.
    // q2 and q4 are intermediate states.
    // q1 and q3 are final states.
     
    static boolean q1(String s, int i)
    {
        state_transition.add("q1");
        if (i == s.length())
        {
            return false;
        }
     
        // state transitions
        // a takes to q1, b takes to q2
        if (s.charAt(i) == 'a')
            return q1(s, i + 1);
        else
            return q2(s, i + 1);
    }
     
    static boolean q2(String s, int i)
    {
        state_transition.add("q2");
        if (i == s.length())
        {
            return true;
        }
     
        // state transitions
        // a takes to q1, b takes to q2
        if (s.charAt(i) == 'a')
            return q1(s, i + 1);
        else
            return q2(s, i + 1);
    }
     
    static boolean q3(String s, int i)
    {
        state_transition.add("q3");
        if (i == s.length())
        {
            return false;
        }
     
        // state transitions
        // a takes to q4, 1 takes to q3
        if (s.charAt(i) == 'a')
            return q4(s, i + 1);
        else
            return q3(s, i + 1);
    }
     
    static boolean q4(String s, int i)
    {
        state_transition.add("q4");
        if (i == s.length())
        {
            return true;
        }
     
        // state transitions
        // a takes to q4, b takes to q3
        if (s.charAt(i) == 'a')
            return q4(s, i + 1);
        else
            return q3(s, i + 1);
    }
     
    static boolean q0(String s, int i)
    {
        state_transition.add("q0");
        if (i == s.length())
        {
            return false;
        }
     
        // state transitions
        // a takes to q1, b takes to q3
        if (s.charAt(i) == 'a')
            return q1(s, i + 1);
        else
            return q3(s, i + 1);
    }
     
    // Driver code
    public static void main (String[] args)
    {
        String s = "ababab";
     
        // all state transitions are printed.
        // if string is acceptable, print YES.
        // else NO is printed
        boolean ans = q0(s, 0);
        if (ans == true)
        {
            System.out.println("YES");
     
            // print transition state of given
            // string str
            for(int index = 0; index < state_transition.size(); index++)
            { //(auto& it : ) {
                System.out.print((String)state_transition.get(index) + ' ');
            }
        }
        else
            System.out.println("NO");
    }
}
 
// This code is contributed by AnkitRai01


Python3
# Python3 Program to DFA that accepts
# if it starts and end with
# same character
 
 
# vector to store state transition
state_transition = []
 
# end position is checked using string
# length value.
# q0 is the starting state.
# q2 and q4 are intermediate states.
# q1 and q3 are final states.
def q1(s, i):
 
    state_transition.append("q1")
    if (i == len(s)):
        return False
 
    # state transitions
    # a takes to q1, b takes to q2
    if (s[i] == 'a'):
        return q1(s, i + 1)
    else:
        return q2(s, i + 1)
 
def q2(s, i):
 
    state_transition.append("q2")
    if (i == len(s)):
        return True
 
    # state transitions
    # a takes to q1, b takes to q2
    if (s[i] == 'a'):
        return q1(s, i + 1)
    else:
        return q2(s, i + 1)
 
def q3(s, i):
 
    state_transition.append("q3")
    if (i == len(s)):
        return False
 
    # state transitions
    # a takes to q4, 1 takes to q3
    if (s[i] == 'a'):
        return q4(s, i + 1)
    else:
        return q3(s, i + 1)
 
def q4(s, i):
 
    state_transition.append("q4")
    if (i == len(s)):
        return True
 
    # state transitions
    # a takes to q4, b takes to q3
    if (s[i] == 'a'):
        return q4(s, i + 1)
    else:
        return q3(s, i + 1)
 
def q0(s, i):
 
    state_transition.append("q0")
    if (i == len(s)):
        return False
 
    # state transitions
    # a takes to q1, b takes to q3
    if (s[i] == 'a'):
        return q1(s, i + 1)
    else:
        return q3(s, i + 1)
 
s = "ababab"
 
# all state transitions are printed.
# if is acceptable, print YES.
# else NO is printed
ans = q0(s, 0)
if (ans):
    print("YES")
 
    # print transition state of given
    # str
    for it in state_transition:
        print(it, end = " ")
 
else:
    print("NO")
 
# This code is contributed by mohit kumar 29


C#
// C# Program to DFA that accepts
// string if it starts and end with
// same character
using System;
using System.Collections;
class GFG{
      
// vector to store state transition
static ArrayList state_transition =
                 new ArrayList();
      
// end position is checked using
// string length value.
// q0 is the starting state.
// q2 and q4 are intermediate
// states. q1 and q3 are final
// states.     
static bool q1(string s, int i)
{
  state_transition.Add("q1");
  if (i == s.Length)
  {
    return false;
  }
 
  // state transitions
  // a takes to q1, b
  // takes to q2
  if (s[i] == 'a')
    return q1(s, i + 1);
  else
    return q2(s, i + 1);
}
 
static bool q2(string s, int i)
{
  state_transition.Add("q2");
  if (i == s.Length)
  {
    return true;
  }
 
  // state transitions
  // a takes to q1, b takes to q2
  if (s[i] == 'a')
    return q1(s, i + 1);
  else
    return q2(s, i + 1);
}
      
static bool q3(string s, int i)
{
  state_transition.Add("q3");
  if (i == s.Length)
  {
    return false;
  }
 
  // state transitions
  // a takes to q4, 1
  // takes to q3
  if (s[i] == 'a')
    return q4(s, i + 1);
  else
    return q3(s, i + 1);
}
      
static bool q4(string s, int i)
{
  state_transition.Add("q4");
  if (i == s.Length)
  {
    return true;
  }
 
  // state transitions
  // a takes to q4, b
  // takes to q3
  if (s[i] == 'a')
    return q4(s, i + 1);
  else
    return q3(s, i + 1);
}
      
static bool q0(string s, int i)
{
  state_transition.Add("q0");
  if (i == s.Length)
  {
    return false;
  }
 
  // state transitions
  // a takes to q1, b
  // takes to q3
  if (s[i] == 'a')
    return q1(s, i + 1);
  else
    return q3(s, i + 1);
}
      
// Driver code
public static void Main (string[] args)
{
  string s = "ababab";
 
  // all state transitions are
  // printed. If string is
  // acceptable, print YES.
  // else NO is printed
  bool ans = q0(s, 0);
 
  if (ans == true)
  {
    Console.Write("YES\n");
 
    // print transition state
    // of given string str
    for(int index = 0;
            index < state_transition.Count;
            index++)
    {
      //(auto& it : ) {
      Console.Write(
      (string)state_transition[index] + ' ');
    }
  }
  else
    Console.Write("NO");
}
}
 
// This code is contributed bt rutvik_56


输出:
YES
q0 q1 q2 q1 q2 q1 q2


时间复杂度: O(n) ,其中长度为n的字符串需要遍历n个状态。