简体   繁体   English

跳过Java if语句

[英]Java if-statement being skipped

The method below takes in a string and a pattern and returns true if they match each other. 下面的方法接受一个字符串和一个模式,如果它们相互匹配则返回true A '.' 一种 '。' matches 1 char and a '*' matches 0 or more (eg expMatch("abc", "ac") should return true ). 匹配1个字符,'*'匹配0或更多(例如expMatch("abc", "ac")应该返回true )。 I added a bunch of print statements to see where I went wrong and it seems like the if statement is being skipped even if the str.length() == 1 . 我添加了一堆print语句来查看我出错的地方,即使str.length() == 1 ,似乎也会跳过if语句。

I call it with System.out.println(expMatch("abc", "a*c")); 我用System.out.println(expMatch("abc", "a*c"));调用它System.out.println(expMatch("abc", "a*c"));

Here is the code: 这是代码:

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;           
}

and the output is: 输出是:

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

Even if the length is 1 it skips the if? 即使长度为1,它也会跳过if? Any idea why? 知道为什么吗? PS I'm not looking for the solution, just why the if statement is being skipped. PS我不是在寻找解决方案,只是为什么要跳过if语句。

You always return false from the method at the very end. 你总是从最后的方法返回false。 You are calling expmatch recursively but never using the return value. 您以递归方式调用expmatch但从不使用返回值。 The code comes in to the first if, recurses (because length is not 1) and upon returning will go to the final return statement which returns false. 代码进入第一个if,recurses(因为length不是1)并且在返回时将转到返回false的最终return语句。

You need to add a return before your expMatch() calls - because the false comes from your last line return false; 你需要在expMatch()调用之前添加一个返回 - 因为false来自你的最后一行return false;

What happens is this: 这是怎么回事:

  • you call expMatch() with the two Strings. 你使用两个字符串调用expMatch()。
  • you enter the if clause 你输入if子句
  • the if clause enters expMatch() recursively if子句以递归方式输入expMatch()
  • you enter the else clause 你输入else子句
  • the else clause enters expMatch() recursively else子句以递归方式输入expMatch()
  • you enter the if clause again 再次输入if子句
  • you leave the expMatch() method 你离开了expMatch()方法
  • you leave the other expMatch method 你离开了另一个expMatch方法
  • false is returned 返回false

Your approach is logically incorrect even if you apply the fixes the others suggested. 即使您应用其他人建议的修补程序,您的方法在逻辑上也是不正确的。 Try this test case: 试试这个测试用例:

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

This is because when you encounter a * in the pattern, you have no way to know how many characters "to eat" from the search string. 这是因为当你在模式中遇到*时,你无法知道搜索字符串中有多少字符“吃”。

To say the least, you need a loop somewhere, not just an if . 至少可以说,你需要一个循环,而不仅仅是一个if Let me try to fix it for you (not sure if it's possible though, not sure if you always know which path to take, I mean in your recursion). 让我试着为你修复它(不确定它是否可能,不确定你是否总是知道要采取哪条路径,我的意思是你的递归)。 Think some more about it. 想一想更多。 Here is another unpleasant test case: 这是另一个令人不快的测试用例:

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  

I think you need some sort of full search here. 我想你需要在这里进行一些完整的搜索。
Just an if or a while loop is not good enough. 只是一个ifwhile循环不够好。

EDIT : Here is a fixed version with a bunch of nasty tests. 编辑 :这是一个固定版本与一堆讨厌的测试。 I think this is called non-linear recursion (as it's not a single path you try). 我认为这称为非线性递归 (因为它不是你尝试的单一路径)。 Not 100% sure though about that term. 关于那个词,不是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;
            }
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM