Java:通配符模式匹配

时间:2016-04-01 16:47:17

标签: java pattern-matching wildcard

我一直在尝试解决Wildcard模式匹配,我在下面的链接中找到了一个可行的解决方案:

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()方法中,有没有其他方法可以使这个工作?

1 个答案:

答案 0 :(得分:0)

:)

首先我注意到代码&& (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.length()!= 0 ,因此条件总是假的,因为长度不能为0而不是0同时。

我发现了两个问题。第一个问题是像matches("ge?ks*", "geeksforgeeks")这样的一些案例最终会在格式上出现一个通配符并因{em> format.charAt(1)而在if (format.charAt(0) == '*' && format.charAt(1) != 0 && data.length() == 0)崩溃。为了解决这个问题,我将下一个代码添加到算法中:

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