[英]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: 这是怎么回事:
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. 只是一个
if
或while
循环不够好。
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.