Java:通配符模式匹配



我一直在尝试解决通配符模式匹配问题,并在以下链接中找到了一个有效的解决方案:

http://www.geeksforgeeks.org/wildcard-character-matching/

我已经为上面链接中给出的C代码编写了一个等效的java代码,它是:

    public class wildcard
{
    public static void main(String[] args) 
    {
        test("g*ks", "geeks"); 
        //test("g*k", "gee"); 
        //test("c*d*", "cad");
}
static boolean matches(String format, String data)
{

    if (format.length() == 0 && data.length() == 0)
    {
        return true;
    }
    if ((format.charAt(0) == '*' && format.charAt(1) != 0 && data.length() == 0) && (format.length() != 0 && data.length() != 0))
    {
        return false;
    }
    if ((format.charAt(0) == '?' || format.charAt(0)  == data.charAt(0)) && (format.length() != 0 && data.length() != 0))
    {
        return matches(format.substring(1), data.substring(1));
    }
    if ((format.charAt(0) == '*')&& (format.length() != 0 && data.length() != 0))
    {
        return matches(format.substring(1), data) || matches(format, data.substring(1));
    }

    return false;
}
static void test(String first, String second)
{ 
    System.out.println(matches(first, second)); 
}
}

在执行时,抛出一个字符串越界异常,它是:

    Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 1
at java.lang.String.charAt(String.java:658)
at wildcard.matches(wildcard.java:29)
at wildcard.matches(wildcard.java:36)
at wildcard.matches(wildcard.java:42)
at wildcard.matches(wildcard.java:42)
at wildcard.matches(wildcard.java:36)
at wildcard.test(wildcard.java:52)
at wildcard.main(wildcard.java:16)

我可以看到这个异常发生在CharAt()方法上,有其他方法可以实现吗??

:)

首先,我注意到代码&(format.length()!=0&data.length()!=0)不在您提供的页面的原始代码中,并且导致与您的算法发生冲突,因此我将其删除,看起来如下:

static boolean matches(String format, String data) {
    if (format.length() == 0 && data.length() == 0) {
        return true;
    }
    if (format.charAt(0) == '*' && format.charAt(1) != 0 && data.length() == 0) {
        return false;
    }
    if (format.charAt(0) == '?' || format.charAt(0) == data.charAt(0)) {
        return matches(format.substring(1), data.substring(1));
    }
    if (format.charAt(0) == '*') {
        return matches(format.substring(1), data) || matches(format, data.substring(1));
    }
    return false;
}

我谈到的问题是在第二个条件中,您有data.length()==0,而在我删除的代码中是data.lenght()!=0,因此该条件始终为false,因为长度不能同时为0而不是0。

我发现了两个问题。第一种情况是,像matches("ge?ks*", "geeksforgeeks")这样的一些情况最终在格式上有一个通配符,并且由于格式而在if (format.charAt(0) == '*' && format.charAt(1) != 0 && data.length() == 0)上崩溃。charAt(1)。为了解决这个问题,我在算法中添加了下一个代码:

if (format.length() == 1 && format.charAt(0) == '*')
        return true;

另一个问题是当格式为空但仍有数据并使用解决时

if (format.length() == 0 && data.length() > 0)
        return false;

最后的算法是这样的:

static boolean matches(String format, String data) {
    if (format.length() == 0 && data.length() == 0)
        return true;
    if (format.length() == 1 && format.charAt(0) == '*')
        return true;
    if (format.length() == 0 && data.length() > 0)
        return false;
    if (format.charAt(0) == '*' && format.charAt(1) != 0 && data.length() == 0)
        return false;
    if (format.charAt(0) == '?' || format.charAt(0) == data.charAt(0))
        return matches(format.substring(1), data.substring(1));
    if (format.charAt(0) == '*')
        return matches(format.substring(1), data) || matches(format, data.substring(1));
    return false;
}

最新更新