-5

我需要在 C++ 中设计一个图灵机模拟器,它接受一个输入文件,如下所示:

Q:q1,q2,q3,q4
A:0,1
Z:0,1,x
T:q1,0,q2,x,R
T:q1,1,q2,x,R
T:q2,0,q2 ,0,R
...
S:q1
F:q3,q4

其中 Q 是状态,A 是输入值,Z 是磁带字母表,S 是开始状态,F 是接受和拒绝状态。

它需要处理一个输入,其中包含输入数量、输入字符串以及接受或拒绝。

所以如果输入的是:
3
0,#,1,1
1,1
0,1,0

输出将打印出步骤以及它是接受还是拒绝。

我需要创建一个执行算术运算的 TM,一个执行字符串运算的 TM,以及我选择的另一个。

任何有关如何开始的帮助表示赞赏。

4

2 回答 2

2

尝试这样的事情:

#include <iostream>
#include <string.h>
#include <vector>
#include <fstream>
#include <cstdlib>
#include <stdio.h>
#include "tm.h"

using namespace std;

tm::tm(char *fn)
{
    current = "";
    readFile(fn);
}

void tm::readFile(char *fn)
{
    char temp;
    string word = "";
    ifstream indata;
    bool blank = false;
    indata.open(fn); //opens the file
    if(!indata) //error message if the file is unable to be opened
    {   
        cout << "Could not open the specified file \"" << fn << "\"" << endl;
        exit(1);
    }
    indata >> temp;
    while (!indata.eof())
    {
        if (temp == 'Q')
        {
            //cout << "Q" << endl;
            indata >> temp;
            indata >> temp; //skip the :
            while (temp != 'A')
            {
                if (temp != ',') word += temp;
                else
                {
                    QQ.push_back(word);
                    word = "";
                }
                indata >> temp;
            }
            QQ.push_back(word);
            word = "";
        }
        else if (temp == 'A')
        {
            //cout << "A" << endl;
            indata >> temp;
            indata >> temp; //skip the :
            while (temp != 'Z')
            {
                if (temp != ',') word += temp;
                else
                {
                    AA.push_back(word);
                    word = "";
                }
                indata >> temp;
            }
            AA.push_back(word);
            word = "";
        }
        else if (temp == 'Z')
        {
            //cout << "Z" << endl;
            indata >> temp;
            indata >> temp; //skip the :
            while (temp != 'T')
            {
                if (temp != ',') word += temp;
                else
                {
                    ZZ.push_back(word);
                    word = "";
                }
                indata >> temp;
            }
            ZZ.push_back(word);
            word = "";
            for (int i = 0; i < (int)ZZ.size(); i++)
                if (ZZ[i].compare(" ") == 0)
                    blank = true;
            if (blank == false) //no blanks were found in the tape alphabet
                ZZ.push_back(" ");
        }
        else if (temp == 'T')
        {
            //cout << "T" << endl;
            indata >> temp;
            indata >> temp; //skip the :
            bool wasComma = false;
            vector<string> row;
            while (temp != 'T' && temp != 'S')
            {
                if (wasComma && temp == ',') //the last one was a comma
                {
                    row.push_back(" ");
                    wasComma = false;
                }
                else if (temp != ',')
                {
                    word += temp;
                    wasComma = false;
                }
                else
                {
                    row.push_back(word);
                    word = "";
                    wasComma = true;
                }
                indata >> temp;
            }
            row.push_back(word);
            TT.push_back(row);
            word = "";
        }
        else if (temp == 'S')
        {
            //cout << "S" << endl;
            indata >> temp;
            indata >> temp; //skip the :
        while (temp != 'F')
            {
                if (temp != ',') word += temp;
                else
                {
                    SS = word;
                    word = "";
                }
                indata >> temp;
            }
            SS = word;
            word = "";
        }
        else if (temp == 'F')
        {
            //cout << "F" << endl;
            indata >> temp;
            indata >> temp; //skip the :
            while (!indata.eof())
            {
                if (temp != ',')
                    word += temp;
                else
                {
                    FF.push_back(word);
                    word = "";
                }
                indata >> temp;
            }
            FF.push_back(word);
            word = "";
        }
    }   
    indata.close();
    readInput();
    runAll();
    return;
}

void tm::readInput()
{
    int num, k;
    cin >> num;

    string temp;
    getline(cin,temp);
    getline(cin,temp);
    for (int i = 0; i < num; i++) //num is the number of rows of input to the machine
{
        vector<string> row;
        string word = "";
        for(k = 0; k < (int)temp.size(); k++)
        {
            if (temp[k] != ',')
                word += temp[k];
            else if ((int)word.size() > 0)
            {
                row.push_back(word);
                word = "";
            }
            if (k == (int)temp.size() -1 && (int)word.size() > 0)
            {
                row.push_back(word);
                word = "";
            }
    }
        if (k > 0)
            input.push_back(row);
        else //if there is an empty row of input to the machine
        {
            vector<string> row;
            row.push_back("e");
            input.push_back(row);
        }
        getline(cin,temp);
    }

    return;
}

void tm::runAll()
{
    checkForAlphabetBlanks();
    checkTransitions();
    checkStart();
    checkFinal();
    checkDeterministic();
    checkAcceptReject();
    checkInput();

    int currentPosition;
    string currentState, currentSymbol;
    bool found, first = true;
    for (int i = 0; i < (int)input.size(); i++) //for each row of the input
    {
        if (first != true)
            cout << endl;
        first = false;
        currentPosition = 0;
        currentState = SS;
        for (int k = 0; k < 1000; k++) //for each character of input, then up to 1000
        {
            if (k == 0) //the first time
            {
                if (0 < (int)input[i].size()) //we are not past the right of the tape
                    currentSymbol = input[i][0];
                else
                    currentSymbol = " ";
                cout << "()" << SS << "(";
                for (int g = 0; g < (int)input[i].size(); g++)
                {
                    cout << input[i][g];
                    if (g != (int)input[i].size() - 1) //it is not the last input
                        cout << ",";
                    else
                        cout << ")" << endl;
                }
            }
            if (currentState.compare(FF[0]) == 0) //check if we are accept
            {
                cout << "ACCEPT" << endl;
                break;
            }
            else if (currentState.compare(FF[1]) == 0) //check if we are reject
            {
                cout << "REJECT" << endl;
                break;
            }
            found = false;
            for (int g = 0; g < (int)TT.size(); g++)
            {
                if (TT[g][0].compare(currentState) == 0 && TT[g][1].compare(currentSymbol) == 0) //same state and symbol as the transition line
                {
                    found = true;
                    currentState = TT[g][2];
                    input[i][currentPosition] = TT[g][3];
                    if (TT[g][4].compare("R") == 0) currentPosition++;
                    else currentPosition--;
                    //check for out of bounds to the left
                    if (currentPosition < 0) currentPosition = 0;
                    cout << "(";
                    for (int t = 0; t < currentPosition; t++)
                    {
                        cout << input[i][t];
                        if (t != currentPosition - 1) cout << ","; //not the last one
                    }
                    cout << ")" << currentState << "(";
                    for (int t = currentPosition; t < (int)input[i].size(); t++)
                    {
                        cout << input[i][t];
                        if (t != (int)input[i].size() - 1) cout << ","; //not the last one
                    }
                    cout << ")" << endl;
                    if (currentPosition < (int)input[i].size()) currentSymbol = input[i][currentPosition]; //not past the right side of the tape
                    else
                    {
                        currentSymbol = " ";
                        input[i].push_back(" ");
                    }
                    break;
                }
            }
            if (found == true) //a transition was found
            {
                if (currentState.compare(FF[0]) == 0) //check if accept
                {
                    cout << "ACCEPT" << endl;
                    break;
                }
                else if (currentState.compare(FF[1]) == 0) //check if reject
                {
                    cout << "REJECT" << endl;
                    break;
                }
            }
            else
            {
                currentPosition++;
                cout << "(";
                for (int t = 0; t < currentPosition; t++)
                {
                    cout << input[i][t];
                    if (t != currentPosition - 1) cout << ","; //not the last one
                }
                cout << ")" << FF[1] << "(";
                for (int t = currentPosition; t < (int)input[i].size(); t++)
                {
                    cout << input[i][t];
                    if (t != (int)input[i].size() - 1) cout << ","; //not the last one
                }
                cout << ")" << endl;
                cout << "REJECT" << endl;
                break;
            }
            if (k == 999)
                cout << "DID NOT HALT" << endl;
        }
    }

    return;
}

void tm::checkForAlphabetBlanks()
{
    for (int i = 0; i < (int)AA.size(); i++)
    {
        if (AA[i].compare(" ") == 0)
        {
            cout << "The alphabet has a blank space." << endl;
            exit(1);
        }
    }
    return;
}

void tm::checkTransitions()
{
    bool state1, state2, character1, character2;

    for (int i = 0; i < (int)TT.size(); i++)
    {
    //check the direction
        if (TT[i][4].compare("R") != 0 && TT[i][4].compare("L") != 0)
        {
            cout << "The only valid directions are R and L." << endl;
            exit(1);
        }
        //check the states
        state1 = false; state2 = false;
        for (int k = 0; k < (int)QQ.size(); k++)
        {
            if (TT[i][0].compare(QQ[k]) == 0) state1 = true;
            if (TT[i][2].compare(QQ[k]) == 0) state2 = true;
        }
        if (state1 == false)
        {
            cout << "The state " << TT[i][0] << " in transition function number " << i << " is not in the list of states." << endl;
            exit(1);
        }
        if (state2 == false)
        {
            cout << "The state " << TT[i][2] << " in transition function number " << i << " is not in the list of states." << endl;
            exit(1);
        }
        //check the characters
        character1 = false; character2 = false;
        for (int k = 0; k < (int)ZZ.size(); k++)
        {
            if (TT[i][1].compare(ZZ[k]) == 0) character1 = true;
            if (TT[i][3].compare(ZZ[k]) == 0) character2 = true;
        }
        if (character1 == false)
        {
            cout << "The character '" << TT[i][1] << "' in transition function number " << i << " is not in the tape alphabet." << endl;
            exit(1);
        }
        if (character2 == false)
        {
            cout << "The character '" << TT[i][3] << "' in transition function number " << i << " is not in the tape alphabet." << endl;
            exit(1);
        }
}
    return;
}

void tm::checkStart()
{
    bool in = false;
    for (int i = 0; i < (int)QQ.size(); i++)
    {
        if (SS.compare(QQ[i]) == 0) in = true;
    }
    if (in == false)
    {
        cout << "The start state " << SS << " is not in the list of states." << endl;
        exit(1);
    }
}

void tm::checkFinal()
{
    if (FF[0].compare(FF[1]) == 0)
    {
        cout << "The accept and reject states cannot be the same." << endl;
        exit(1);
    }
    bool accept = false, reject = false;
    for (int i = 0; i < (int)QQ.size(); i++)
    {
        if (FF[0].compare(QQ[i]) == 0) accept = true;
        if (FF[1].compare(QQ[i]) == 0) reject = true;
        }
        if (accept == false)
        {
        cout << "The accept state " << FF[0] << " is not in the list of states." << endl;
        exit(1);
    }
    if (reject == false)
    {
        cout << "The reject state " << FF[1] << " is not in the list of states." << endl;
        exit(1);
    }
}

void tm::checkDeterministic()
{
    for (int i = 0; i < (int)TT.size(); i++)
        for (int k = i+1; k < (int)TT.size(); k++)
            if (TT[i][0].compare(TT[k][0]) == 0 && TT[i][1].compare(TT[k][1]) == 0)
            {
            cout << "The machine cannot proceed deterministically, transitions " << i << " and " << k << " are the same." << endl;
            exit(1);
        }
}

void tm::checkAcceptReject()
{
    for (int i = 0; i < (int)TT.size(); i++)
    {
        if (TT[i][0].compare(FF[0]) == 0 || TT[i][0].compare(FF[1]) == 0)
        {
            cout << "The machine cannot transitions from the accept or reject states." << endl;
        }
    }
}

void tm::checkInput()
{
    bool exists;
    for (int i = 0; i < (int)input.size(); i++)
    {
        for (int k = 0; k < (int)input[i].size(); k++)
        {
            exists = false;
            for (int g = 0; g < (int)AA.size(); g++)
            {
                if (input[i][k].compare(AA[g]) == 0) exists = true;
            }
            if (exists == false)
            {
                if (input[i][0].compare("e") != 0) //it is not 'e'
                {
                    cout << "The input character " << input[i][k] << " is not in the input alphabet." << endl;
                    exit(1);
                }
            }
        }
    }
}
于 2012-05-08T17:48:26.913 回答
0

您可以模仿文件压缩器:给定一串字符并将重复序列压缩为 8 个组(添加更大的组将需要线性数量的更多代码行,添加更多字符将需要指数数量的更多行代码,因为每个字母都需要对每个可能的字母做出反应。)

机器记录磁带的正面,然后一直运行到背面。它“吃掉”角色,将相似的角色放入一个扩大的池中。当达到限制、磁带的末端或达到另一个字符类型时,机器会打印它已经走了多远,然后开始堆积新的字符。

Q:q0,q1,q2,Fs,Rs,a1,a1z,a2,a2z,a3,a3z,a4,a4z,a5,a5z,a6,a6z,a7,a7z,b1,b1y,b2,b2y,b3,b3y,b4,b4y,b5,b5y,b6,b6y,b7,b7y
A:a,b
Z: ,a,a2,a3,a4,a5,a6,a7,a8,b,b2,b3,b4,b5,b6,b7,b8,y,z 
T:q0,a,q1,y,R
T:q0,b,q1,z,R   
T:q1,a,q1,a,R
T:q1,b,q1,b,R
T:q1, ,q2, ,L    
T:q2,a,a1, ,L
T:q2,b,b1, ,L
T:q2,y,Fs,a,R
T:q2,z,Fs,b,R  
T:a1,a,a2, ,L
T:a1,b,b1,a,L
T:a1,y,Fs,a2,R
T:a1,z,a1z,b,R
T:a1z, ,Fs,a,R    
T:b1,b,b2, ,L
T:b1,a,a1,b,L
T:b1,z,Fs,b2,R
T:b1,y,b1y,a,R
T:b1y, ,Fs,b,R    
T:a2,a,a3, ,L
T:a2,b,b1,a2,L
T:a2,y,Fs,a3,R
T:a2,z,a2z,b,R
T:a2z, ,Fs,a2,R    
T:b2,b,b3, ,L
T:b2,a,a1,b2,L
T:b2,z,Fs,b3,R
T:b2,y,b2y,a,R
T:b2y, ,Fs,b2,R   
T:a3,a,a4, ,L
T:a3,b,b1,a3,L
T:a3,y,Fs,a4,R
T:a3,z,a3z,b,R
T:a3z, ,Fs,a3,R   
T:b3,b,b4, ,L
T:b3,a,a1,b3,L
T:b3,z,Fs,b4,R
T:b3,y,b3y,a,R
T:b3y, ,Fs,b3,R   
T:a4,a,a5, ,L
T:a4,b,b1,a4,L
T:a4,y,Fs,a5,R
T:a4,z,a4z,b,R
T:a4z, ,Fs,a4,R 
T:b4,b,b5, ,L
T:b4,a,a1,b4,L
T:b4,z,Fs,b5,R
T:b4,y,b4y,a,R
T:b4y, ,Fs,b4,R  
T:a5,a,a6, ,L
T:a5,b,b1,a5,L
T:a5,y,Fs,a6,R
T:a5,z,a5z,b,R
T:a5z, ,Fs,a5,R   
T:b5,b,b6, ,L
T:b5,a,a1,b5,L
T:b5,z,Fs,b6,R
T:b5,y,b5y,a,R
T:b5y, ,Fs,b5,R    
T:a6,a,a7, ,L
T:a6,b,b1,a6,L
T:a6,y,Fs,a7,R
T:a6,z,a6z,b,R
T:a6z, ,Fs,a7,R   
T:b6,b,b7, ,L
T:b6,a,a1,b6,L
T:b6,z,Fs,b7,R
T:b6,y,b6y,a,R
T:b6y, ,Fs,b7,R
T:a7,a,q2,a8,L
T:a7,b,b1,a7,L
T:a7,y,Fs,a8,R
T:a7,z,a7z,b,R
T:a7z, ,Fs,a7,R
T:b7,b,q2,b8,L
T:b7,a,a1,b8,L
T:b7,z,Fs,b8,R
T:b7,y,b7y,a,R
T:b7y, ,Fs,b7,R

S:q0
F:Fs,Rs

您可以模仿 RNA 碱基对的读取来创建细胞生物学中的氨基酸。用户给出一个完全由 a、c、g 和 u 组成的字符串。机器读取这条线,直到它读取起始密码子“a,u,g”,此时它开始将 RNA 翻译成氨基酸。它会一直执行此操作,直到到达字符串的末尾或到达终止密码子(“UAA”、“UGA”、“UAG”)。如果它到达一个终止密码子,它将继续沿着字符串向下,直到它读取另一个起始密码子或字符串终止。读取任何氨基酸序列都会导致接受,并且不需要到达终止密码子(如生物学)。但是,没有起始密码子的字符串将导致拒绝语句。

第一个示例演示了几个字符延迟,一个起始密码子,然后是氨基酸,直到一个终止密码子,然后是更多未使用的字符,然后是完成。第二个示例演示了起始密码子、中间密码子、终止密码子、填充符、另一个起始密码子和直到字符串完成的密码子。第三个示例演示了无起始密码子和 REJECT 状态。

Q:q0,q1,q2,q3,q4,q5,q6,Fs,Rs,s1,s2,u,c,a,g,uu,ua,ug,ca,au,aa,ag,ga
A:u,c,a,g,u
Z: ,u,c,a,g,ala,arg,asn,asp,cys,gln,glu,gly,his,ile,leu,lem,lys,met,phe,pro,ser,thr,trp,tyr,val,stop

T:q0,u,q0, ,R
T:q0,c,q0, ,R
T:q0,g,q0, ,R
T:q0,a,q1, ,R

T:q1,c,q0, ,R
T:q1,g,q0, ,R
T:q1,a,q0, ,R
T:q1,u,q2, ,R

T:q2,u,q0, ,R
T:q2,c,q0, ,R
T:q2,a,q0, ,R
T:q2,g,q3,met,R

T:q4,u,q4, ,R
T:q4,c,q4, ,R
T:q4,g,q4, ,R
T:q4,a,q5, ,R
T:q4, ,Fs, ,R

T:q5,c,q4, ,R
T:q5,g,q4, ,R
T:q5,a,q4, ,R
T:q5,u,q6, ,R
T:q5, ,Fs, ,R

T:q6,u,q4, ,R
T:q6,c,q4, ,R
T:q6,a,q4, ,R
T:q6,g,q3,met,R
T:q6, ,Fs, ,R

T:s1,u,q3, ,R
T:s1,c,q3, ,R
T:s1,a,q3, ,R
T:s1,g,q3, ,R
T:s1, ,s2, ,L

T:s2,ala,Fs, ,R
T:s2,arg,Fs, ,R
T:s2,gly,Fs, ,R
T:s2,leu,Fs, ,R
T:s2,pro,Fs, ,R
T:s2,ser,Fs, ,R
T:s2,thr,Fs, ,R
T:s2,val,Fs, ,R

T:q3,u,u, ,R
T:q3,c,c, ,R
T:q3,a,a, ,R
T:q3,g,g, ,R
T:q3, ,Fs, ,R

T:u,u,uu, ,R
T:u,c,s1,ser,R
T:u,a,ua, ,R
T:u,g,ug, ,R
T:u, ,Fs, ,R

T:uu,u,q3,phe,R
T:uu,c,q3,phe,R
T:uu,a,q3,leu,R
T:uu,g,q3,leu,R
T:uu, ,Fs, ,R

T:ua,u,q3,tyr,R
T:ua,c,q3,tyr,R
T:ua,a,q4,stop,R
T:ua,g,q4,stop,R
T:ua, ,Fs, ,R

T:ug,u,q3,cys,R
T:ug,c,q3,cys,R
T:ug,a,q4,stop,R
T:ug,g,q3,trp,R
T:ug, ,Fs, ,R

T:c,u,s1,leu,R
T:c,c,s1,pro,R
T:c,a,ca, ,R
T:c,g,s1,arg,R
T:c, ,Fs, ,R

T:ca,u,q3,his,R
T:ca,c,q3,his,R
T:ca,a,q3,gln,R
T:ca,g,q3,gln,R
T:ca, ,Fs, ,R

T:a,u,au, ,R
T:a,c,s1,thr,R
T:a,a,aa, ,R
T:a,g,ag, ,R
T:a, ,Fs, ,R

T:au,u,q3,ile,R
T:au,c,q3,ile,R
T:au,a,q3,ile,R
T:au,g,q3,met,R
T:au, ,Fs, ,R

T:aa,u,q3,asn,R
T:aa,c,q3,asn,R
T:aa,a,q3,lys,R
T:aa,g,q3,lys,R
T:aa, ,Fs, ,R

T:ag,u,q3,ser,R
T:ag,c,q3,ser,R
T:ag,a,q3,arg,R
T:ag,g,q3,arg,R
T:ag, ,Fs, ,R

T:g,u,s1,val,R
T:g,c,s1,ala,R
T:g,a,ga, ,R
T:g,g,s1,gly,R
T:g, ,Fs, ,R

T:ga,u,q3,asp,R
T:ga,c,q3,asp,R
T:ga,a,q3,glu,R
T:ga,g,q3,glu,R
T:ga, ,Fs, ,R

S:q0
F:Fs,Rs
于 2012-05-08T18:01:20.870 回答