如何在给定列表中查找匹配项

发布于 2025-01-13 08:15:51 字数 1079 浏览 1 评论 0原文

我想编写一个方法,该方法将一个由空格分隔的 String key 和一个 String 列表作为输入,其中必须匹配搜索过。

字符串key的格式可能是这样的:

“s1 s2 s3 s4”

必须将其转换为条件“(s1 or s2) and (s3 or s4)",其中条件按 分组or 总是先执行。

该方法应返回与从指定“键”获取的条件相匹配的字符串列表。

public List<String> search(String key, ArrayList<String> s){
    ...
}

输入的示例(一个和一个列表):

// if ((s.contains("i") || s.contains("you")) && (s.contains("boy") || s.contains("girl")) then store in the List and return finally
String key = "i or you boy or girl"; 

ArrayList<String> s = new ArrayList<String>(
            Arrays.asList("hello world",
                          "i am a boy",
                          "i am a girl"));

那么结果列表将包含字符串:

`"i am a boy"` and `"i am a girl"`.

I want to write a method that takes as an input a String key separated by white spaces and a list of String in which matches have to be searched.

The format of the string key could be like this:

"s1 or s2 s3 or s4"

It has to be translated to a condition "(s1 or s2) and (s3 or s4)", where conditions grouped with or are always executed first.

The method should return a list of strings which match the condition obtained from the specified the "key".

public List<String> search(String key, ArrayList<String> s){
    ...
}

Example of the input (a key and a list):

// if ((s.contains("i") || s.contains("you")) && (s.contains("boy") || s.contains("girl")) then store in the List and return finally
String key = "i or you boy or girl"; 

ArrayList<String> s = new ArrayList<String>(
            Arrays.asList("hello world",
                          "i am a boy",
                          "i am a girl"));

Then the resulting list would contain string:

`"i am a boy"` and `"i am a girl"`.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

旧情别恋 2025-01-20 08:15:52

可以使用 谓词由布尔条件表示的函数)和正则表达式

总体思路是根据字符串 key 生成一个 Predicate,然后根据该谓词测试列表元素。

解析 Predicate 的过程按以下步骤完成:

  • 将键拆分为组,然后根据以下正则表达式 使用逻辑 AND 进行组合“(?
    • (? - 负向后查找,表示匹配字符串之前的字符组,不得等于 "or";
    • (?!or) - 负向前视,表示匹配字符串之后的一组字符,不得等于 "or" ;
    • \\s+ - 匹配由一个或多个空格组成的字符串。


  • 将上一步获得的每组字符串在"或"上进行拆分,并将获得的谓词与逻辑OR组合起来。
  • 将上一步生成的谓词组合成单个谓词。

有关正则表达式的信息,请查看本教程 >)

然后我们需要迭代给定的列表并将组合谓词的方法 test() 应用于每个元素。符合谓词的元素将被添加到结果列表中。

public static void main(String[] args) {
    String key = "i or you boy or girl";

    List<String> source =
            List.of("hello world", "i am a boy", "i am a girl");

    Predicate<String> predicate = getPredicate(key);
    List<String> result = new ArrayList<>();

    for (String next: source) {
        if (predicate.test(next)) {
            result.add(next);
        }
    }
    System.out.println(result);
}

public static Predicate<String> getPredicate(String key) {
    Predicate<String> result = str -> true;

    for (String next: key.split("(?<!or)\\s+(?!or)")) {
        Predicate<String> pred = str -> false;

        for (String target: next.strip().split(" or ")) {
            if (target.isEmpty()) {
                continue;
            }
            pred = pred.or(str -> str.contains(target));
        }
        result = result.and(pred);
    }
    return result;
}

输出

[i am a boy, i am a girl]

注意:

  • 将谓词与 (||) 组合的基础必须产生false< /code> 因为只有在这种情况下它才不会影响结果(with (||) 只有一个条件可以为true 总体结果将被评估为true)。
  • 将谓词与 (&&) 组合的基数必须返回 true,因为只有这样结果才不会受到影响 (with && all 条件需要评估为 true 才能使总体结果为 <代码>true)。

It can be done with predicates (function represented by a boolean condition) and regular expressions.

The overall idea is to generator a Predicate based on string key and then to test list elements against this predicate.

The process of parsing a Predicate is done in following steps:

  • Split the key into groups, that has to be combined afterwards with logical AND, based on following regular expression "(?<!or)\\s+(?!or)"
    • (?<!or) - negative lookbehind, represents group of characters before the matching string that must not be equal to "or";
    • (?!or) - negative lookahead, represents group of characters after the matching string that must not be equal to "or";
    • \\s+ - matches a string comprised from one or more white spaces.
  • Split each group of strings obtained at the previous step on the " or " and combine the obtained predicates with logical OR.
  • Combine predicates generated at previous step into a single predicate.

(for information on regular expressions take a look at this tutorial)

Then we need to iterate over the given list and apply method test() of the combined predicate to every element. Elements that meet with the predicate will be added into the resulting list.

public static void main(String[] args) {
    String key = "i or you boy or girl";

    List<String> source =
            List.of("hello world", "i am a boy", "i am a girl");

    Predicate<String> predicate = getPredicate(key);
    List<String> result = new ArrayList<>();

    for (String next: source) {
        if (predicate.test(next)) {
            result.add(next);
        }
    }
    System.out.println(result);
}

public static Predicate<String> getPredicate(String key) {
    Predicate<String> result = str -> true;

    for (String next: key.split("(?<!or)\\s+(?!or)")) {
        Predicate<String> pred = str -> false;

        for (String target: next.strip().split(" or ")) {
            if (target.isEmpty()) {
                continue;
            }
            pred = pred.or(str -> str.contains(target));
        }
        result = result.and(pred);
    }
    return result;
}

Output

[i am a boy, i am a girl]

Note:

  • A base for combining predicates with or (||) has to yield false because only in this case it'll not affect the result (with (||) only one condition can be true and the overall result will be evaluated to true).
  • A base for combining predicates with and (&&) has to return true because only so the result will not get affected (with && all the conditions needs to be evaluated to true for the overall result to be true).
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文