【问题标题】:automata, check string is accepted by language | C++ [closed]自动机,检查字符串被语言接受 | C++ [关闭]
【发布时间】:2016-05-07 04:42:29
【问题描述】:

这是我的自动机,该语言的正则表达式是(aaa*b|ba)a*

我想制作一个 C++ 程序来检查输入字符串是否被该语言接受。

这个程序获取字符串并打印AcceptedRejected

例如:

输入: aaaba - 输出:接受

输入: baa - 输出:接受

输入: aaa - 输出:被拒绝

【问题讨论】:

  • 被拒绝 ....
  • 不知道哪个白痴赞成这个“问题”
  • 您可能误解了我的评论(对不起,这只是讽刺和双关语)。您的问题实际上太宽泛且离题,因此拒绝
  • 我在 c++ 中为有限状态自动机开发了一个不错的框架,可能对你有用:STTCL
  • 如有任何疑问,请随时咨询。

标签: c++ finite-automata automata


【解决方案1】:
#include <string>
#include <iostream>

bool check_string(const std::string& s) {
  static constexpr int INV = -1;
  static constexpr int INITIAL_STATE = 0;
  static constexpr int ACCEPTING_STATE = 3;
  static const int transition_table[5][2] = {
    //  a    b
    {   1,   2   },  // 0
    {   4,  INV  },  // 1
    {   3,  INV  },  // 2
    {   3,  INV  },  // 3
    {   4,   3   }   // 4
  };

  int state = INITIAL_STATE;
  for (char c : s) {
    if (c != 'a' && c != 'b') return false;
    state = transition_table[state][c - 'a'];
    if (state == INV) return false;
  }
  return state == ACCEPTING_STATE;
}

int main(int argc, char* argv[]) {
  if (argc != 2) {
    std::cerr << "Usage: check str\n";
    return 1;
  }
  if (check_string(argv[1]))
    std::cout << "Accepted\n";
  else
    std::cout << "Rejected\n";
  return 0;
}

【讨论】:

    【解决方案2】:

    您完成了大部分工作,因为您的 DFA 绝对正确。让我做剩下的工作。

    让我们考虑一个函数,它将字符串作为参数并根据字符串被接受还是拒绝返回真或假。

    关键思想

    主要思想是使用有限状态机状态,逐步处理字符串。代码写起来非常简单直接,因为它只是遍历不同状态并处理输入字符串通过不同状态的有限状态机,就像您的自动机一样。

    我们从状态 0 开始,按照你的自动机图进行

    这里是一个简短的描述。

    如果字符串以 a 开头,则下一个状态是 1 。如果字符串以 b 开头,则下一个状态为 2,如果字符串不以任何开头,则字符串被拒绝。

    下一个字符是 a 无论当前状态是 1 还是 2 并且下一个字符不是 a ,字符串都会被拒绝。

    如果下一个字符是 a ,则下一个状态是 3 或 4,具体取决于当前状态。

    一旦我们处理好这一点,如果当前状态为 3,那么我们只需要考虑 aa......aaa 直到字符串结尾,如果在任何时候出现其他字符,则字符串被拒绝。

    如果当前状态是 4 ,我们再次处理 aa......aaa 但我们现在还必须看到在 aa.....aaa 之后也出现了一次 b ,然后我们再次保重啊……啊啊啊。

    bool check_string(string str)
    {
     int state = 0;    
    
     if(str[i] == 'a')
      { state = 1; ++i; }
    
     else if(str[i] == 'b')
      { state = 2; ++i; }
    
     else return false;
    
     if(str[i] != 'a')
      return false;
    
     else if(state == 1)
      {state = 4; ++i; }
    
     else if(state == 2)  
      {state = 3; ++i; }
    
     if(state == 3)
     {
       while(i < str.length())
       {
        if(str[i++] != 'a')
         return false;
       }
       return true;
     }
    
     if(state == 4)
     {
      while(i < str.length()&& str[i++] == 'a')
       {
    
       }
      if(i == str.length())
       return false;
      else if(str[i] == 'b')
      {
       while(i < str.length())
       {
        if(str[i++] != 'a')
         return false;
       }
       return true;
      }
      else return false;
    }
    

    【讨论】:

    • 嗯。 if else cascades 或 switch 在处理状态和转换时变得混乱。
    • @πάνταῥεῖ 在这种情况下不是,因为我们有最少的嵌套,而大多数 if else 没有嵌套。只有当你做嵌套时它才会变得凌乱
    • @πάνταῥεῖ 只需按照图表,代码就会像一段代码一样读给你听。
    • 我更喜欢其他技术(状态设计模式)。
    • @πάνταῥεῖ 如果您有更好的答案,请发布。我希望看到更好的答案。
    猜你喜欢
    • 2016-01-13
    • 2020-08-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多