【问题标题】:Finite State Machine to Search for "ABBA"搜索“ABBA”的有限状态机
【发布时间】:2018-01-04 19:30:12
【问题描述】:

我正在尝试编写一个 while switch case 代码,用于对有限状态机进行建模,该状态机搜索一串 As 和 Bs 以查看字符串“ABBA”是否存在。当我只输入“ABBA”时,它会像预期的那样输出Word found!。但是,如果我输入 "AABBA" 它找不到单词并输出正确的消息。任何帮助表示赞赏。谢谢!

import java.util.*;
public class AB{
    public static void main(String args[]){
        Scanner input = new Scanner(System.in);
        String word = input.next();
        int current = 0;
        int status = 0;
        System.out.println("Starting to evaluate...");
        while(status != 4){
            for(int i = current; i < word.length(); i++){
                String part = word.substring(current, i + 1);
                switch(status){
                    case 0: //start
                        if(part.equals("A")){
                            status = 1;
                        }
                        else if(part.equals("B"){
                            status = 0; 
                            current = i;
                        }
                    break;
                    case 1: //A is there now
                        if(part.equals("AB")){
                            status = 2;
                        }
                        else if(part.equals("AA"){
                            status = 1;
                            current = 1;
                        }
                    break;
                    case 2: //AB is there now
                        if(part.equals("ABB")){
                            status = 3;
                        }
                        else if(part.equals("ABA"){
                            status = 1;
                            current = 1;
                        }
                    break;
                    case 3: //ABB is there now
                        if(part.equals("ABBA")){
                            status = 4;
                            System.out.println("Word found!");
                        }
                        else if(part.equals("ABBB"){
                            status = 0;
                            current = i;
                        }
                    break;
                }
            }
        }
    }
}

【问题讨论】:

  • while/switch 构造是必需的吗?
  • @AlexeyR。是的
  • 我将 String word = input.next() 更改为 String word = "AABBA" 并且效果很好。你确定不是扫描仪问题。
  • 附注 - 在状态机中,在每个步骤中只比较“下一个”字母更有意义。前面的字母已经在前面的步骤中测试过了,它们让你进入了当前的状态 (status x),所以不需要再次比较整个字符串,只需额外的字符。
  • 它实际上找到了AABBA。请注意,如果您提供的第一个单词不包含ABBA,您的程序将永远卡在while 循环中

标签: java fsm


【解决方案1】:

我认为您的方法无效的是您实际上没有使用状态机的功能。首先,您应该了解是什么驱动您的机器通过这些状态。在您的示例中,输入字符串的每个连续字母都是如此。既然你已经进入了一个状态,你现在应该检查下一个符号将你的机器切换到哪个状态。让我建议以下实现..

这是状态图:

这是实现该图的代码:

public boolean abbaMatcher(String abba)
{
    int state = 0;
    int symbol = 0;


    while (symbol < abba.length()){
        char c = abba.charAt(symbol);
        switch (state){
            case 0: if(c == 'a'){
                        state = 1;
                    }else{
                        state = 0;
                    };
                    break;
            case 1: if(c == 'b'){
                        state = 2;
                    }else{
                        state = 1;
                    };
                    break;
            case 2: if(c == 'b'){
                        state = 3;
                    }else{
                        state = 1;
                    };
                    break;
            case 3: if(c == 'a'){
                        return true;
                    }else{
                        state = 0;
                    };
                    break;
        }
        symbol++;
    }

    return false;
}

这可以用一个 for 循环更容易地编写,但是 while/switch 构造是必需的。

【讨论】:

  • 您应该说明您对 OP 代码所做的更改以及为什么您的代码会更好。您还应该解决他们代码中的问题。仅仅说“改用这段代码”是没有帮助的。
  • 你刚刚帮别人做了功课。对于明显抽象且类似于家庭作业的问题,考虑可以引导他们修复解决方案而不是放弃答案的问题通常是个好主意。不是投反对票或其他任何东西,只是一个建议。
  • 我喜欢它,但如果你添加转换图来理解你的所有实现会更好。
  • @JorgeOmarMedra 我想添加一个,但我不确定是否有一种可靠的方法可以将图片粘贴到此处,以便“保存多年”
  • @AlexeyR。是的,栏工具中有一个选项可以添加图片,您可以在其中拖放它。它在Code SaplmeJavaScript/HTML/CSS Snipped 之间。
【解决方案2】:

以下代码与您的实现类似,但它考虑了动态序列(不同的序列),并且不会混淆子字符串,而是迭代字符串的底层字符数组。

它还考虑了以另一个序列开始的序列,例如:在字符串"ABABAB" 中查找序列"ABAB" 将在索引0 找到"ABAB",在索引2 找到"ABAB" . 这可以通过注释掉wIndex = startIndex 轻松删除。

代码:

public static void main (String[] args) throws java.lang.Exception {
    // Scanner input = new Scanner(System.in);
    String word = "B BABBABBA B";
    String seq = "ABBA";
    char[] wChars = word.toCharArray();
    char[] sChars = seq.toCharArray();
    int wIndex = 0; // wChars index
    int sIndex = 0; // sChars index
    int startIndex = 0; // starting index of the seq found in wChars

    System.out.println("Starting to evaluate...");

    while(wIndex < wChars.length) {
        if(wChars[wIndex] == sChars[sIndex]) {
            if(sIndex == 0) {
                startIndex = wIndex;
            }
            sIndex += 1;
        } else {
            sIndex = 0;
        }

        if(sIndex >= sChars.length) {
            System.out.println("Sequence \"" + seq + "\" found at index " + startIndex + ".");
            sIndex = 0;
            wIndex = startIndex; // set wIndex to startIndex to account for
                                 // sequence within a sequence, basically
                                 // backtracking
        }

        wIndex += 1;
    }
}

输出:

Starting to evaluate...
Sequence "ABBA" found at index 3.
Sequence "ABBA" found at index 6.

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-10
    • 1970-01-01
    相关资源
    最近更新 更多