对如何实现这种有限状态机感到困惑

时间:2015-03-24 04:25:54

标签: java

假设我有一个由一组字符序列组成的字符串 { 'd', 'P', 'S', 'W'} 每个角色都代表一个单词 “干”,“油漆”,“沙子”和“擦拭”

有限状态机实现令我困惑,这是一个图

enter image description here

我也可以发布我的代码

公共类州{

public static void main(String[] args) {
    String s = "";
    int currentState = 0;

    for (int i = 0; i < s.length(); i += 1) {
        char c = s.charAt(i);

        switch (currentState) {
        case 0:

            if (c == 'P') {
                currentState = 2;
            } else if (c == 'S') {
                currentState = 1;
            } else {
                System.out.println("false");

            }
            break;
        case 1:
            if (c == 'W') {
                currentState = 3;
            } else {
                System.out.println("false");
            }
            break;
        case 2:
            if (c == 'D') {
                currentState = 0;
            } else if (c == 'S') {
                currentState = 1;
            }
            System.out.println("false");
        }
        break;
        case 3:
            if(c == 'P') {
                currentState = 2;
            } else if(c == 'S') {
                currentState = 1;
            }
            System.out.println("False");

    }
    System.out.println(currentState == 3);
}

3 个答案:

答案 0 :(得分:0)

目前,您已将其以图形格式实施。

查找以表格格式隐藏(或记录)此内容的各种方法。当你有转换表时,就可以将它们编码到编程语言中,程序保存当前状态,接受输入,然后根据转换表转换状态。

状态表的示例可以在维基百科http://en.wikipedia.org/wiki/State_transition_table

找到

将图表中的转换映射到表中,然后编写一个例程,将初始状态设置为变量,然后请求输入,并根据表中编码的值进行转换。执行转换部分的最简单方法是使用数据结构将表编码到程序本身中。

下面有目的的不完整代码应该会给你一个快速启动。

public class StateInput {

    private int state;

    private char input;

    public StateInput(int state, char input) {
        this.state = state;
        this.input = input;
    }

    @Override
    public int hashCode() {
        int hash = 5;
        hash = 83 * hash + this.state;
        hash = 83 * hash + this.input;
        return hash;
    }

    public boolean equals(Object object) {
        if (object instanceof StateInput) {
            StateInput other = (StateInput)object;
            return state == other.state && input == other.input;
        }
        return false;
    }

}


public class Machine {

    private Map<StateInput, Integer> transitionTable;

    private final int initialState;

    private int currentState;

    private Set<Integer> acceptanceStates;

    public Machine() {
        ... code goes here ...
        currentState = initialState;
    }

    public void readInput(char input) {
        Integer newState = transitionTable.get(StateInput(curentState, input));
        if (newState == null) {
            throw new IllegalStateException("no transition for input");
        } else {
            currentState = newState;
        }
    }

    public boolean isAcceptable() {
        return acceptanceStates.contains(currentState);
    }

}

答案 1 :(得分:0)

好吧,你的疑问有点困惑,但你从状态0开始,是你的初始状态,所以,如果你读到或发现了一个&#39; P&#39;你去了州2,从那里你需要检查一下是什么,根据你的图表,如果你读了一个&#39; D&#39;你返回状态0 :),其他字母和状态相同

我看到你的代码,你必须从状态0开始

//从状态0开始   int currentState = 0;

并且您的案例0必须是案例2,案例1必须是案例0:)

答案 2 :(得分:0)

你需要一个状态变量来告诉你你所处的状态。你需要一个转换函数来获取这个状态变量和一个输入。您案例中的输入将是序列中的一个单词。

转换函数然后相应地更改状态变量。 您可以从状态变量上的开关开始,然后调用基于当前状态评估输入的子函数。这样你的过渡功能就不会过大。

最后,您需要一个将整个程序输入(参见String.split)拆分为转换函数输入的函数。 使用初始状态启动状态变量。对于输入的每个部分(通常称为令牌),请调用转换函数。输出状态变量。

我不会给你代码。这看起来太像家庭作业了;)