【问题标题】:Matching a pattern in an ArrayList of Strings匹配字符串 ArrayList 中的模式
【发布时间】:2018-12-01 23:48:29
【问题描述】:

我正在尝试匹配 ArrayList 中项目之间的模式。到目前为止我已经做到了,但是有一个问题。我已经做到了,所以* 匹配 ArrayList 中的任何项目。以及我如何开始匹配​​是通过对第一个模式项进行 indexOf ,但如果第一项是 * 它不起作用,因为它试图 indexOf * 不作为一个项目存在。

所以基本上这里是代码。

public boolean matchPattern(String... strings) {
    int indexOfItem = getList().indexOf(strings[0]);
    if (indexOfItem != -1) {
        for (int i = 0; i < strings.length; i++) {
            int listIndex = indexOfItem + i;
            String s = strings[i];
            if (Objects.equals("*", s)) {
                continue;
            }
            if (!Objects.equals(getList().get(listIndex), s)) {
                return false;
            }
        }
        return true;
    }
    return false;
}

问题发生在这一行

int indexOfItem = getList().indexOf(strings[0]);

strings[0] 返回*

有人可以告诉我如何使用* 作为第一项来完成这项工作吗?在这一点上我一无所知。基本上一个模式会是这样的

*、1、2、3、*、5

这将成功匹配以下内容

0、1、2、3、4、5

随机、随机、0、1、2、3、4、5'

但不匹配

0、1、随机、3、4、5

随机、随机、0、1、随机、3、4、5

PS:这只是一个例子,我真的不想匹配数字。

【问题讨论】:

  • 这没有任何意义 - 你传递了一个 String 的数组,你试图匹配什么模式?这应该什么时候返回true
  • 为什么要专门检查第一个元素?为什么不只对所有元素进行循环和循环?
  • 如果你的第一个项目是星号,那么你应该返回 true,因为每个项目都会匹配,不是吗?如果是,那么: if (strings[0].equals("asterisk")) return true;
  • @ElliottFrisch 这应该只在所有项目都连续匹配时返回 true。它们可以在列表中的任何位置,但如果它们不在一行中,则必须在一行中返回 false
  • @Skaparate 仅当所有项目连续匹配时才返回 true,而不仅仅是一个。

标签: java arrays pattern-matching


【解决方案1】:

想出了一个适用于我尝试过的测试用例的解决方案,如果有人知道此代码在某些情况下可能会失败,请随时发布答案。

public static int findPattern(List<String> strings, String... pattern) {
    findFirstString:
    for (int startIndex = 0; startIndex <= strings.size() - pattern.length; startIndex++) {
        for (int i = 0; i < pattern.length; i++) {
            String p = pattern[i];
            if (!"*".equals(p) && !strings.get(startIndex + i).equals(p)) {
                continue findFirstString;
            }
        }
        return startIndex;
    }
    return -1;
}

然后我使用!= -1 检查模式是否匹配我需要索引,因为我正在向索引中注入一些数据。

【讨论】:

    【解决方案2】:

    由于您是模式匹配,因此可以使用正则表达式在一行中完成!

    从输入构建一个正则表达式,将通配符转换为"[^,]+",然后针对它测试数组:

    /** @return -1 if no hit, otherwise the index of the first element of the part that matches */
    public int matchPattern(String... strings) {
        String head = getList().toString().replaceAll("(.*)?\\b" + String.join(", ", strings).replace("*", "[^,]+") + "\\b.*", "$1");
        return head.isEmpty() ? -1 : head.replaceAll("[^,]", "").length();
    }
    

    【讨论】:

    • 如果列表项模式不是从索引 0 开始,这将不起作用。
    • 已编辑问题
    • 我认为从 0 开始是明智的假设。那么两端对齐吗?
    • 不,模式可以在列表中的任何位置,但必须在一行中才能匹配。我已经用 2 个循环解决了它。
    • 我已经发布了对我有用的答案,请看看它在某些测试用例中是否会失败。
    猜你喜欢
    • 1970-01-01
    • 2018-10-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-17
    • 1970-01-01
    • 2011-03-29
    相关资源
    最近更新 更多