跳过Java if语句

时间:2015-02-09 21:47:27

标签: java if-statement recursion

下面的方法接受字符串和模式,如果彼此匹配则返回 true 。 A'。'匹配1个字符和一个' *'匹配0或更多(例如expMatch("abc", "a.c")应返回 true )。我添加了一堆打印语句来查看我出错的地方,即使str.length() == 1,似乎也会跳过if语句。

我用System.out.println(expMatch("abc", "a*c"));

来称呼它

以下是代码:

public static boolean expMatch(String str, String pat)
{   
    if (str.charAt(0) == pat.charAt(0) || pat.charAt(0) == '.')
    {
        System.out.println("in if");
        System.out.println(str.charAt(0));
        System.out.println(pat.charAt(0));
        System.out.println(str.length());
        if (str.length() == 1)
            return true;
        expMatch(str.substring(1), pat.substring(1));
    }

    else if (pat.charAt(0) == '*')
    {   
        System.out.println("in else");
        System.out.println(str.charAt(0));
        System.out.println(pat.charAt(0));
        if (str.length() == 1)
            return true;
        if (str.charAt(0) == pat.charAt(1)) //val of * = 0
            expMatch(str, pat.substring(1));
        else if (str.charAt(1) ==pat.charAt(1))
            expMatch(str.substring(1), pat.substring(1));           
    }

    return false;           
}

,输出为:

in if
a
a
3
in else
b
*
in if
c
c
1
false

即使长度为1,它也会跳过if?知道为什么吗? 附:我没有找到解决方案,只是为什么要跳过if语句。

3 个答案:

答案 0 :(得分:6)

总是从最后的方法返回false。您以递归方式调用expmatch但从不使用返回值。代码进入第一个if,recurses(因为length不是1)并且在返回时将转到返回false的最终return语句。

答案 1 :(得分:4)

您需要在expMatch()调用之前添加一个返回值 - 因为false来自您的最后一行return false;

这是怎么回事:

  • 使用两个字符串调用expMatch()。
  • 您输入if子句
  • if子句递归地输入expMatch()
  • 您输入了else子句
  • else子句以递归方式输入expMatch()
  • 再次输入if子句
  • 你离开了expMatch()方法
  • 你离开了另一个expMatch方法
  • 返回false

答案 2 :(得分:3)

即使您应用其他人建议的修补程序,您的方法在逻辑上也是不正确的。试试这个测试用例:

System.out.println(expMatch("abddddc", "a*c"));

这是因为当您在模式中遇到*时,您无法知道搜索字符串中有多少字符“吃”。

至少可以说,你需要一个循环,而不仅仅是if。让我试着为你修复它(不确定它是否可能,不确定你是否总是知道要采取哪条路径,我的意思是你的递归)。想一想更多。这是另一个令人不快的测试用例:

System.out.println(expMatch("adddcac", "a*c")); 
// the * needs to eat dddca (despite the c present in dddca),  
// it should not stop recursing there at that c  

我认为你需要在这里进行一些完整的搜索 只有ifwhile循环不够好。

编辑:这是一个固定版本,有一堆讨厌的测试。我认为这被称为非线性递归(因为它不是你尝试的单一路径)。关于那个词,不是100%肯定。

public class Test055 {

    public static void main(String[] args) {
        // System.out.println(expMatch("abddddc", "a*c"));

        System.out.println(expMatch("adcax", "a*c"));
        System.out.println(expMatch("adcax", "a*c*"));

        System.out.println(expMatch("adcacm", "*"));
        System.out.println(expMatch("adcacmmm", "a*c"));
        System.out.println(expMatch("adcacmmmc", "a*c"));
        System.out.println(expMatch("adcac", "a*c"));

        System.out.println(expMatch("adcacxb", "a*c.b"));
        System.out.println(expMatch("adcacyyb", "a*c.b"));
        System.out.println(expMatch("adcacyyb", "a*c*b"));

    }

    public static boolean expMatch(String str, String pat)
    {
        // System.out.println("=====================");
        // System.out.println("str=" + str);
        // System.out.println("pat=" + pat);

        if (pat.length() == 0 && str.length() > 0) {
            return false;
        } else if (pat.length() == 0 && str.length() == 0) {
            return true;
        } else if (pat.charAt(0) == '.'){
            return str.length() >= 1 && expMatch(str.substring(1), pat.substring(1));
        }else if (pat.charAt(0) != '*'){
            return str.length() >= 1 && pat.charAt(0) == str.charAt(0) && expMatch(str.substring(1), pat.substring(1));
        }else{
            // Now let's handle the tricky part

            // (1) Look for the 1st non-star in pattern
            int k=-1;
            char ch = ' ';
            for (int i=0; i<pat.length(); i++){
                if (pat.charAt(i) != '*'){
                    k = i;
                    ch = pat.charAt(k);
                    break;
                }
            }

            if (k==-1){
                // (2A) only stars found in pattern, OK, any str matches that
                return true;
            }else{
                // (2B) do full search now checking all  
                // possible candidate chars in str that 
                // match the char ch from pattern
                for (int i=0; i<str.length(); i++){
                    if (str.charAt(i)==ch){
                        boolean b = expMatch(str.substring(i+1), pat.substring(k+1));
                        if (b) return true;
                    }
                }
                return false;
            }
        }
    }
}