这是我的自动机,此语言的正则表达式为(aaa*b|ba)a*
我想为这个语言接受检查输入字符串的C ++程序。
此程序获取字符串并打印Accepted
或Rejected
例如:
输入: aaaba - 输出:已接受
输入: baa - 输出:已接受
输入: aaa - 输出:已拒绝
答案 0 :(得分:2)
#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;
}
答案 1 :(得分:1)
您完成了大部分工作,因为您的DFA绝对正确。请允许我做剩下的工作。
让我们考虑一个函数,该函数将字符串作为参数并返回true或false,具体取决于字符串是被接受还是被拒绝。
关键理念
主要思想是使用有限状态机状态并逐步处理字符串。代码非常简单直接编写,因为它只是有限状态机遍历不同的状态,并且通过不同的状态处理输入字符串,就像你的自动机一样。
我们从状态0开始,并按照自动机的图表
以下是简要说明。
如果字符串以a开头,则下一个状态为1。如果字符串以b开头,则下一个状态为2,如果字符串以none开头,则拒绝该字符串。
下一个字符是a,无论当前状态是1还是2而下一个字符不是a,字符串都会被拒绝。
如果下一个字符是a,则下一个状态是3或4,具体取决于当前状态。
一旦我们处理了这个,如果当前状态是3,那么我们只需要考虑aa ...... aaa直到字符串的结尾,如果在任何点发生某些其他字符,则字符串被拒绝。
如果当前状态是4,我们再次照顾aa ...... aaa但是我们现在还必须看到aa ..... aaa之后还有一次出现b然后我们再次照顾aa ........ aaa。
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;
}