0

以下は、DFA (決定論的有限オートマトン) を実装する簡単なプログラムです。ただし、私の問題には DFA は関係ありません。

#include<iostream>
using namespace std;

int main()
{
    char c;
    int state=1;
    while((c=cin.get())!='4')
    {
        switch(state)
        {
            case 1:
            if(c=='0')
            state=2;
            if(c=='1')
            state=1;
            if(c=='2')
            state=2;

            break;

            case 2:
            if(c=='0')
            state=5;
            if(c=='1')
            state=1;
            if(c=='2')
            state=3;

            break;

            case 3:
            if(c=='0')
            state=1;
            if(c=='1')
            state=5;
            if(c=='2')
            state=4;

            break;

            case 4:
            if(c=='0')
            state=3;
            if(c=='1')
            state=4;
            if(c=='2')
            state=5;

            break;

            case 5:
            if(c=='0')
            state=5;
            if(c=='1')
            state=4;
            if(c=='2')
            state=1;

            break;

            default:
            cout<<"Input will not be accepted"<<endl;

        } //switch
        cout<<"Current state is "<<state<<endl; 
    } //while


    return 0;
}

コードを実行すると、すべての行が 2 回出力されていることがわかりました。たとえば、0 1 0 0 4 と入力すると、DFA は 1->2->1->2->5 の状態になるため、出力は次のようになります。

Current state is 2
Current state is 1
Current state is 2
Current state is 5

しかし、出力は次のとおりです。

Current state is 2
Current state is 2
Current state is 1
Current state is 1
Current state is 2
Current state is 2
Current state is 5
Current state is 5

誰でも原因を指摘できますか?

4

2 に答える 2

5

cin.get()は 1 文字を読み取るため、スペースも読み取っています。次に、スペースが何にも一致しないため、各スペースの後、プログラムは前の状態を出力するだけです。cin >> c代わりに使用したい。

于 2013-01-26T20:04:46.290 に答える
1

どうやらコードを CodeReview に投稿するつもりはないので、私がコードを書くと思う方法の代替案を投稿させてください。

#include<iostream>
using namespace std;

static const int states[][3] = {
    { 2, 1, 2 },
    { 5, 1, 3 },
    { 1, 5, 4 },
    { 3, 4, 5 },
    { 5, 4, 1 }
};

int main()
{
    char c;
    int state=1;
    while(cin >> c && c != '4') {
        if (c >= '0' && c <= '2')
            state = states[state-1][c-'0'];
        else
            std::cout << "Input will not be accepted.\n";
        cout<<"Current state is "<<state<<"\n"; 
    }
    return 0;
}

少なくとも私には、文字を読み取って入力に基づいて状態をウォークスルーするコードからステート マシン自体を分離することは言うまでもなく、これは読みやすく理解しやすいように思えます。

于 2013-01-27T01:45:47.047 に答える