跳过Java if语句 [英] Java if-statement being skipped
问题描述
下面的方法接受一个字符串和一个模式,如果它们相互匹配则返回 true 。 '。'匹配1个字符,'*'匹配0或更多(例如 expMatch(abc,ac)
应返回 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)
返回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)
返回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));
}
返回false;
}
,输出为:
in if
a
a
3
in else
b
*
in if
c
c
1
false
即使长度也是如此是1它会跳过if吗?知道为什么吗?
P.S.我不是在寻找解决方案,只是为什么要跳过if语句。
你的方法在逻辑上是不正确的,即使您应用其他人建议的修复程序。试试这个测试用例:
System.out.println(expMatch(abddddc,a * c));
这是因为当您在模式中遇到 *
时,您无法知道如何搜索字符串中的许多字符吃。
至少可以说,你需要一个循环,而不仅仅是,如果
。让我试着为你解决它(不确定它是否可能,不确定你是否总是知道要采取哪条路径,我的意思是你的递归)。多想一想。这是另一个令人不快的测试用例:
System.out.println(expMatch(adddcac,a * c)) ;
$处复制p $ p>
// *需要吃dddca(尽管dddca中存在c),
//它不应该停止在那个c
我认为你需要在这里进行某种全面的搜索。
只需如果
或a而
循环不够好。
编辑:这是一个带有大量令人讨厌的测试的固定版本。我认为这被称为非线性递归(因为它不是你尝试的单一路径)。关于那个词,不是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 {
//现在让我们处理棘手的部分
//(1)寻找模式中的第一个非星形
int k = -1 ;
char ch ='';
for(int i = 0; i< pat.length(); i ++){
if(pat.charAt(i)!='*'){
k = i;
ch = pat.charAt(k);
休息;
}
}
if(k == - 1){
//(2A)只在模式中找到星号,OK,任何str匹配
返回true;
} else {
//(2B)现在全面搜索检查所有
// str中可能的候选字符
//匹配来自模式
的char ch for(int i = 0; i< str.length(); i ++){
if(str.charAt(i)== ch){
boolean b = expMatch(str.substring(i +) 1),pat.substring(k + 1));
如果(b)返回true;
}
}
返回false;
}
}
}
}
The method below takes in a string and a pattern and returns true if they match each other. A '.' matches 1 char and a '*' matches 0 or more (e.g.
expMatch("abc", "a.c")
should return 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 thestr.length() == 1
.I call it with
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? Any idea why? P.S. I'm not looking for the solution, just why the if statement is being skipped.
解决方案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
. 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 anif
or awhile
loop is not good enough.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.
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; } } } }
这篇关于跳过Java if语句的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!